elf readelf 段 作用域

sample变量段分析

1.各段地址区间
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 000080f4 0000f4 000014 00 A 0 0 1
[ 2] .hash HASH 00008108 000108 0000cc 04 A 3 0 4
[ 3] .dynsym DYNSYM 000081d4 0001d4 000200 10 A 4 1 4
[ 4] .dynstr STRTAB 000083d4 0003d4 00012f 00 A 0 0 1
[ 5] .rel.plt REL 00008504 000504 0000a8 08 A 3 7 4
[ 6] .init PROGBITS 000085ac 0005ac 000010 00 AX 0 0 4
[ 7] .plt PROGBITS 000085bc 0005bc 000110 04 AX 0 0 4
[ 8] .text PROGBITS 000086cc 0006cc 000448 00 AX 0 0 4
[ 9] .fini PROGBITS 00008b14 000b14 000010 00 AX 0 0 4
[10] .rodata PROGBITS 00008b24 000b24 0000a8 01 AMS 0 0 4
[11] .eh_frame PROGBITS 00008bcc 000bcc 000004 00 A 0 0 4
[12] .init_array INIT_ARRAY 00011000 001000 000004 00 WA 0 0 4
[13] .fini_array FINI_ARRAY 00011004 001004 000004 00 WA 0 0 4
[14] .jcr PROGBITS 00011008 001008 000004 00 WA 0 0 4
[15] .dynamic DYNAMIC 0001100c 00100c 0000c0 08 WA 4 0 4
[16] .got PROGBITS 000110cc 0010cc 000060 04 WA 0 0 4
[17] .data PROGBITS 0001112c 00112c 000408 00 WA 0 0 4
[18] .bss NOBITS 00011534 001534 000424 00 WA 0 0 4
[19] .comment PROGBITS 00000000 001534 00004d 01 MS 0 0 1
[20] .ARM.attributes ARM_ATTRIBUTES 00000000 001581 00002b 00 0 0 1
[21] .debug_aranges PROGBITS 00000000 0015ac 000020 00 0 0 1
[22] .debug_info PROGBITS 00000000 0015cc 000e13 00 0 0 1
[23] .debug_abbrev PROGBITS 00000000 0023df 0002ef 00 0 0 1
[24] .debug_line PROGBITS 00000000 0026ce 0002de 00 0 0 1
[25] .debug_frame PROGBITS 00000000 0029ac 000078 00 0 0 4
[26] .debug_str PROGBITS 00000000 002a24 0005f1 01 MS 0 0 1
[27] .debug_loc PROGBITS 00000000 003015 000221 00 0 0 1
[28] .shstrtab STRTAB 00000000 003236 00010d 00 0 0 1
[29] .symtab SYMTAB 00000000 00381c 000830 10 30 87 4
[30] .strtab STRTAB 00000000 00404c 0003e1 00 0 0 1

2.变量详细位置
2.1 全局变量
char buffer_g_u[BUF_SIZE];
91: 00011554 256 OBJECT GLOBAL DEFAULT 18 buffer_g_u----------------bss段

char buffer_g_i[BUF_SIZE] = "0123456789";
102: 00011134 256 OBJECT GLOBAL DEFAULT 17 buffer_g_i----------------data段

char buffer_g_u_unuse[BUF_SIZE];
100: 00011854 256 OBJECT GLOBAL DEFAULT 18 buffer_g_u_unuse----------bss段

char buffer_g_i_unuse[BUF_SIZE] = "0123456789";
108: 00011434 256 OBJECT GLOBAL DEFAULT 17 buffer_g_i_unuse----------data段

static char buffer_g_s_u[BUF_SIZE];
70: 00011654 256 OBJECT LOCAL DEFAULT 18 buffer_g_s_u--------------bss段

static char buffer_g_s_i[BUF_SIZE] = "0123456789";
65: 00011234 256 OBJECT LOCAL DEFAULT 17 buffer_g_s_i--------------data段

static char buffer_g_s_u_unuse[BUF_SIZE];------------------------------------被优化
static char buffer_g_s_i_unuse[BUF_SIZE] = "0123456789";---------------------被优化

2.2静态变量
char buffer_l_u[BUF_SIZE];---------------------------------------------------被优化
char buffer_l_i[BUF_SIZE] = "0123456789";------------------------------------被优化
char buffer_l_u_unuse[BUF_SIZE];---------------------------------------------被优化
char buffer_l_i_unuse[BUF_SIZE] = "0123456789";------------------------------被优化
static char buffer_l_s_u[BUF_SIZE];
71: 00011754 256 OBJECT LOCAL DEFAULT 18 buffer_l_s_u.5127---------bss段

static char buffer_l_s_i[BUF_SIZE] = "0123456789";
66: 00011334 256 OBJECT LOCAL DEFAULT 17 buffer_l_s_i.5128---------data段

static char buffer_l_s_u_unuse[BUF_SIZE];------------------------------------被优化
static char buffer_l_s_i_unuse[BUF_SIZE] = "0123456789";---------------------被优化


#define _POSIX_C_SOURCE 199309
#include <signal.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/capability.h>
#include <errno.h>

#define TIMER_SIG SIGRTMAX /* Our timer notification signal */
#define BUF_SIZE 256
volatile static unsigned int real_timer_count = 0;
volatile static unsigned int alarm_timer_count = 0;
char buffer_g_u[BUF_SIZE];
char buffer_g_i[BUF_SIZE] = "0123456789";
char buffer_g_u_unuse[BUF_SIZE];
char buffer_g_i_unuse[BUF_SIZE] = "0123456789";
static char buffer_g_s_u[BUF_SIZE];
static char buffer_g_s_i[BUF_SIZE] = "0123456789";
static char buffer_g_s_u_unuse[BUF_SIZE];
static char buffer_g_s_i_unuse[BUF_SIZE] = "0123456789";

char *
currTime(const char *format)
{
char buf_local[BUF_SIZE]; /* Nonreentrant */
time_t t;
size_t s;
struct tm *tm;

t = time(NULL);
tm = localtime(&t);
if (tm == NULL)
return NULL;

s = strftime(buf_local, BUF_SIZE, (format != NULL) ? format : "%c", tm);

return (s == 0) ? NULL : buf_local;
}

static void
alarm_handler(int sig, siginfo_t *si, void *uc)
{
timer_t *tidptr;

tidptr = si->si_value.sival_ptr;

/* UNSAFE: This handler uses non-async-signal-safe functions
(printf(); see Section 21.1.2) */

// printf("[%s] ALARM count=%d\n", currTime("%T"), alarm_timer_count);
alarm_timer_count++;
}

/*
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
#define CLOCK_MONOTONIC_RAW 4
#define CLOCK_REALTIME_COARSE 5
#define CLOCK_MONOTONIC_COARSE 6
#define CLOCK_BOOTTIME 7
#define CLOCK_REALTIME_ALARM 8
#define CLOCK_BOOTTIME_ALARM 9
*/
#define CLOCK_REALTIME_ALARM 8
#define CLOCK_BOOTTIME_ALARM 9
void print_buf(char *buf)
{
time_t t;
size_t s;
struct tm *tm;

t = time(NULL);
tm = localtime(&t);
if (tm == NULL)
return;

s = strftime(buf, sizeof(buf), "%T", tm);
}
int
main(int argc, char *argv[])
{
struct itimerspec ts;
struct sigaction sa;
struct sigevent sev;
timer_t *tidlist;
struct __user_cap_header_struct cap_header;
struct __user_cap_data_struct cap_data[2];

char buffer_l_u[BUF_SIZE];
char buffer_l_i[BUF_SIZE] = "0123456789";
char buffer_l_u_unuse[BUF_SIZE];
char buffer_l_i_unuse[BUF_SIZE] = "0123456789";
static char buffer_l_s_u[BUF_SIZE];
static char buffer_l_s_i[BUF_SIZE] = "0123456789";
static char buffer_l_s_u_unuse[BUF_SIZE];
static char buffer_l_s_i_unuse[BUF_SIZE] = "0123456789";

char buffer_local_main[BUF_SIZE];

char *buffer_alloc, *buffer_alloc_unuse;

buffer_g_u[0] = 1;
buffer_g_i[0] = 1;
buffer_g_s_u[0] = 1;
buffer_g_s_i[0] = 1;

buffer_l_u[0] = 1;
buffer_l_i[0] = 1;
buffer_l_s_u[0] = 1;
buffer_l_s_i[0] = 1;

buffer_alloc = malloc(BUF_SIZE);
buffer_alloc_unuse = malloc(BUF_SIZE);
buffer_alloc[0] = 1;

free(buffer_alloc);
free(buffer_alloc_unuse);
cap_header.pid = getpid();
cap_header.version = _LINUX_CAPABILITY_VERSION_3;
if( capget(&cap_header, cap_data) < 0)
{
printf("%s\n", strerror(errno));
exit(EXIT_FAILURE);
}

printf("capheader: %x %d\n", cap_header.version, cap_header.pid);
printf("capdata: %x %x %x\n", cap_data[0].effective, cap_data[0].permitted, cap_data[0].inheritable);
printf("capdata: %x %x %x\n", cap_data[1].effective, cap_data[1].permitted, cap_data[1].inheritable);
tidlist = calloc(5, sizeof(timer_t));
if (tidlist == NULL)
{
printf("malloc");
return -1;
}

ts.it_value.tv_sec = 20;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = 10;
ts.it_interval.tv_nsec = 0;

printf("[%s] Start timer\n", currTime("%T"));
print_buf(buffer_local_main);
printf("[%s] Start timer\n", buffer_local_main);

sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = alarm_handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGALRM, &sa, NULL) == -1)
{
printf("sigaction");
return -1;
}

sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGALRM;

sev.sigev_value.sival_ptr = &tidlist[1];
if (timer_create(CLOCK_REALTIME_ALARM, &sev, &tidlist[1]) == -1)
{
printf("timer_create CLOCK_REALTIME_ALARM\n");
return -1;
}
if (timer_settime(tidlist[1], 0, &ts, NULL) == -1)
{
printf("timer_settime CLOCK_REALTIME_ALARM\n");
return -1;
}

// sleep(250);
// printf("[%s] Enter sleep\n", currTime("%T"));
// system("echo mem > /sys/power/state");

for (;;) /* Wait for incoming timer signals */
pause();
}

变量类型 是否占用空间
全局变量 不论是否使用,都占用空间。
因为全局变量作用域跨文件,所以即使此文件没有使用,也不能被优化。
全局静态变量 如果没被使用,会被编译器优化。
全局静态变量的作用域为文件,编译器可以判定在此文件是否使用。没有使用,则别处也不会使用。没有存在意义。
如果被使用,则占用空间。
局部变量 局部变量不占用空间。
局部变量只在函数内使用,分配在栈中。
局部静态变量 如果没被使用,会被编译器优化。
局部静态的作用域是函数,虽然存在静态存储区,但是如果函数内没有使用。在别处再不会被使用,所以可以优化掉。
如果被使用,则占用空间。
存在静态存储区。
malloc/free 堆中分配和释放,所以是动态的。

时间: 2024-10-01 18:50:11

elf readelf 段 作用域的相关文章

ELF文件数据布局探索(1)

作为一名Linux小白,第一次看到a.out这个名字,感觉实在是奇怪,搜了一下才知道这是编译器输出的默认可执行文件名 然后vi一下,哇,各种乱码,仔细看看,发现了三个清晰的字符ELF.继续搜索, 第一感觉就是这就是windows下的*.exe 顺便看到了readelf这条命令,就读了一下这个文件,发现这里边好多东西都不懂,后来在学习linux的过程中渐渐明白了 一部分,前几天刚好跟同学说到了关于ELF文件数据布局的问题,今天总结一下(罗嗦了这么多,真是不好意思). 今天讨论的问题是:我们在源程序

Linux ELF 文件格式

ELF 文件类型 ELF (Executable Linkable Format) 是 linux 下的可执行文件格式,与 windows 下的 PE (Portable Executable) 格式一样,都是 COFF (Common File Format)文件格式的变种.在 linux 下除了可执行文件,编译过程中产生的目标文件(.o 文件),动态链接文件(.so 文件),静态链接库文件(.a 文件) ,核心转储文件(Core Dump File)都按照 ELF 格式存储.查看 ELF 文

使用readelf和objdump解析目标文件 ***

引言 本文是对程序员的自我修养:链接.装载与库中第3章的实践总结(和结构相关的示意图都是用Gliffy Diagrams画的??),通过使用工具readelf.objdump对目标文件进行解析,学习目标文件的结构. 1. 目标文件 1.1 目标文件的定义 编译器编译源代码后生成的文件叫做目标文件.在Linux下,使用gcc -c xxxx.c编译生成.o文件. gcc -c xxxx.c编译生成目标文件 1.2 编译过程回顾 编译过程 目标文件的文件类型为ELF,在Linux下对应文件后缀为.o

《程序员的自我修养》第三章学习笔记

1,  编译器编译源代码生成的文件叫做目标文件. 从结构上说,是编译后的可执行文件,只不过还没有经过链接 3.1 目标文件的格式 1,可执行文件的格式: Windows下的PE  和   Linux下的ELF 2,从广义上说,目标文件与可执行文件的格式几乎是一样的,所以广义上可以将目标文件与可执行文件看成是一种类型的文件. 3,可执行文件,动态链接库,静态链接库都按照可执行文件格式存储(Windows下是 PE-COFF格式,Linux下是ELF格式). 4,Linux下命令: $: file 

解析对象体内与方法体内引用内部方法的不同

/*对象体内*/ var a={ init:function(){a.func1();}, //这里要加this或者对象a,但方法体内同等格式不用,思考这其中的差别 func1:function(){alert(1);} } a.init(); //执行 /*方法体内*/ function b(){ this.init=function(){func1();}; //这里可以调用到func1,原因在于对象体没有开辟作用域的概念,它自己依赖于自身所在的作用域,所以不能在对象体中直接找到func1.

C的日记-静态链接和动态链接

[静态链接和动态链接]    静态链接:源程序编译之后,如果想要执行,先对目标文件进行链接,链接完成后如果执行了,就把链接好的都装载进内存    缺点:        <1>如果一个目标文件被重复使用,每次都会把目标文件载入内存,造成浪费:        <2>如果相对某个目标文件进行更新,需要先把这个目标文件重新编译+链接,然后重新载入内存.    动态链接:在程序开始运行后(装载到内存)才开始把目标文件依次加载到内存然后编译成可执行文件    优点:        <1&

Bootstrap 源码解析

Bootstrap 源码解析 1.Bootstrap的作用域 2.Bootstrap的类定义 3.Bootstrap的插件定义 4.Bootstrap的事件代理 5.Bootstrap的对象数据缓存 6.Bootstrap的防冲突 7.作用域外如何使用Button类 8.Bootstrap的单元测试 Bootstrap的作用域 Bootstrap每个插件都定义在下面这段作用域代码中: 请看<IIFE>和<严格模式>编译环境. 在插件的作用域之外,全局范围执行代码的第一行,检测了jQ

Bootstrap 源码解析(转)

1.Bootstrap的作用域 2.Bootstrap的类定义 3.Bootstrap的插件定义 4.Bootstrap的事件代理 5.Bootstrap的对象数据缓存 6.Bootstrap的防冲突 7.作用域外如何使用Button类 8.Bootstrap的单元测试 Bootstrap的作用域 Bootstrap每个插件都定义在下面这段作用域代码中: +function ($) { ... }(window.jQuery) 请看<IIFE>和<严格模式>编译环境. 在插件的作用

linux装载可执行程序简析

朱宇轲 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 linux中主要的可执行文件为ELF文件,我们可以将它装载到自己的程序中,这次我们就将分析linux装载可执行程序的过程. 首先明确一点,装载可执行程序有两种方式:静态链接与动态链接.所谓静态链接,就是在程序执行之前完成所有链接工作,组成一个可执行文件,放到内存执行.这样做的缺点是,当有多个文件要链接同一份可执行文件时,内存