第二部分、字符串表(节,.strtab)。
09 00 00 00 //.strtab 03 00 00 00 //3 ,表明本节是字符串表 00 00 00 00 //标志 00 00 00 00 //还没重定位,所以为0 24 1a 00 00 //起始地址:0x1a24 32 02 00 00 //大小 0×232 00 00 00 00 00 00 00 00 01 00 00 00 //对齐 00 00 00 00 //指向的不是表
根据上面的解析,把字符串表拿出来,地址为0x1a24~0x1c55 00 63 72 74 73 74 75 66 66 2e 63 00 5f 5f 43 54 4f 52 5f 4c 49 53 54 5f 5f 00 5f 5f 44 54 4f 52 5f 4c 49 53 54 5f 5f 00 5f 5f 4a 43 52 5f 4c 49 53 54 5f 5f 00 5f 5f 64 6f 5f 67 6c 6f 62 61 6c 5f 64 74 6f 72 73 5f 61 75 78 00 63 6f 6d 70 6c 65 74 65 64 2e 36 30 38 36 00 64 74 6f 72 5f 69 64 78 2e 36 30 38 38 00 66 72 61 6d 65 5f 64 75 6d 6d 79 00 5f 5f 43 54 4f 52 5f 45 4e 44 5f 5f 00 5f 5f 46 52 41 4d 45 5f 45 4e 44 5f 5f 00 5f 5f 4a 43 52 5f 45 4e 44 5f 5f 00 5f 5f 64 6f 5f 67 6c 6f 62 61 6c 5f 63 74 6f 72 73 5f 61 75 78 00 6c 65 61 66 2e 63 00 5f 5f 69 6e 69 74 5f 61 72 72 61 79 5f 65 6e 64 00 5f 44 59 4e 41 4d 49 43 00 5f 5f 69 6e 69 74 5f 61 72 72 61 79 5f 73 74 61 72 74 00 5f 47 4c 4f 42 41 4c 5f 4f 46 46 53 45 54 5f 54 41 42 4c 45 5f 00 5f 5f 6c 69 62 63 5f 63 73 75 5f 66 69 6e 69 00 5f 5f 69 36 38 36 2e 67 65 74 5f 70 63 5f 74 68 75 6e 6b 2e 62 78 00 64 61 74 61 5f 73 74 61 72 74 00 70 72 69 6e 74 66 40 40 47 4c 49 42 43 5f 32 2e 30 00 5f 65 64 61 74 61 00 5f 66 69 6e 69 00 5f 5f 73 74 61 63 6b 5f 63 68 6b 5f 66 61 69 6c 40 40 47 4c 49 42 43 5f 32 2e 34 00 5f 5f 44 54 4f 52 5f 45 4e 44 5f 5f 00 5f 5f 64 61 74 61 5f 73 74 61 72 74 00 5f 5f 67 6d 6f 6e 5f 73 74 61 72 74 5f 5f 00 5f 5f 64 73 6f 5f 68 61 6e 64 6c 65 00 5f 49 4f 5f 73 74 64 69 6e 5f 75 73 65 64 00 5f 5f 6c 69 62 63 5f 73 74 61 72 74 5f 6d 61 69 6e 40 40 47 4c 49 42 43 5f 32 2e 30 00 5f 5f 6c 69 62 63 5f 63 73 75 5f 69 6e 69 74 00 5f 65 6e 64 00 5f 73 74 61 72 74 00 5f 66 70 5f 68 77 00 5f 5f 62 73 73 5f 73 74 61 72 74 00 6d 61 69 6e 00 5f 4a 76 5f 52 65 67 69 73 74 65 72 43 6c 61 73 73 65 73 00 5f 5f 69 73 6f 63 39 39 5f 73 63 61 6e 66 40 40 47 4c 49 42 43 5f 32 2e 37 00 5f 69 6e 69 74 00
既然是字符串表,那就翻译成ASCII字符串,如下:
crtstuff.c __CTOR_LIST__ __DTOR_LIST__ __JCR_LIST__ __do_global_dtors_aux completed.6086 dtor_idx.6088 frame_dummy __CTOR_END__ __FRAME_END__ __JCR_END__ __do_global_ctors_aux leaf.c __init_array_end _DYNAMIC __init_array_start _GLOBAL_OFFSET_TABLE_ __libc_csu_fini __i686.get_pc_thunk.bx data_start printf@@GLIBC_2.0 _edata _fini __stack_chk_fail@@GLIBC_2.4 __DTOR_END__ __data_start __gmon_start__ __dso_handle _IO_stdin_used __libc_start_main@@GLIBC_2.0 __libc_csu_init _end _start _fp_hw __bss_start main _Jv_RegisterClasses __isoc99_scanf@@GLIBC_2.7 _init
仔细看看上面的字符串,我们会发现我们定义的全局变量和函数的名字都在这里,像printf、scanf、main等。但是printf() 函数调用中用到的字符串(像”input gemfield’s blog:”)却没有发现,它们被定义在.rodata 节中,因为它们是字符串常量。
第三部分、代码节(.text),数据如下:
92 00 00 00 //.text 01 00 00 00 //1 ,程序定义 06 00 00 00 /表示此节内容是指令代码,并且要使用内存单元 d0 83 04 08 //代码映射到虚拟内存中的起始地址,为0x080483d0,记住这个数字。 d0 03 00 00 //在gemfield中的偏移地址 0x03d0 dc 01 00 00 //大小 0x1dc个字节 00 00 00 00 // 00 00 00 00 10 00 00 00 //对齐 00 00 00 00 //指向的不是表
我们把这个代码段的数据拿出来,地址为0x3d0~0x5ab,如下:
31 ed 5e 89 e1 83 e4 f0 50 54 52 68 70 85 04 08 68 00 85 04 08 51 56 68 84 84 04 08 e8 bf ff ff ff f4 90 90 90 90 90 90 90 90 90 90 90 90 90 90 55 89 e5 53 83 ec 04 80 3d 1c a0 04 08 00 75 3f a1 20 a0 04 08 bb 20 9f 04 08 81 eb 1c 9f 04 08 c1 fb 02 83 eb 01 39 d8 73 1e 8d b6 00 00 00 00 83 c0 01 a3 20 a0 04 08 ff 14 85 1c 9f 04 08 a1 20 a0 04 08 39 d8 72 e8 c6 05 1c a0 04 08 01 83 c4 04 5b 5d c3 8d 74 26 00 8d bc 27 00 00 00 00 55 89 e5 83 ec 18 a1 24 9f 04 08 85 c0 74 12 b8 00 00 00 00 85 c0 74 09 c7 04 24 24 9f 04 08 ff d0 c9 c3 90 55 89 e5 83 e4 f0 83 ec 50 8b 45 0c 89 44 24 1c 65 a1 14 00 00 00 89 44 24 4c 31 c0 c7 44 24 28 00 00 00 00 b8 d0 85 04 08 89 04 24 e8 cb fe ff ff b8 e8 85 04 08 8d 54 24 2c 89 54 24 04 89 04 24 e8 f6 fe ff ff b8 eb 85 04 08 8d 54 24 2c 89 54 24 04 89 04 24 e8 a1 fe ff ff 8b 54 24 4c 65 33 15 14 00 00 00 74 05 e8 9f fe ff ff c9 c3 90 90 90 90 90 90 90 90 90 90 90 90 90 55 57 56 53 e8 69 00 00 00 81 c3 eb 1a 00 00 83 ec 1c 8b 6c 24 30 8d bb 20 ff ff ff e8 1b fe ff ff 8d 83 20 ff ff ff 29 c7 c1 ff 02 85 ff 74 29 31 f6 8d b6 00 00 00 00 8b 44 24 38 89 2c 24 89 44 24 08 8b 44 24 34 89 44 24 04 ff 94 b3 20 ff ff ff 83 c6 01 39 fe 75 df 83 c4 1c 5b 5e 5f 5d c3 eb 0d 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 c3 8b 1c 24 c3 90 90 90 90 90 90 90 90 90 90 55 89 e5 53 83 ec 04 a1 14 9f 04 08 83 f8 ff 74 13 bb 14 9f 04 08 66 90 83 eb 04 ff d0 8b 03 83 f8 ff 75 f4 83 c4 04 5b 5d c3 90 90
我们使用反汇编 objdump –disassemble gemfield,输出如下: ***************************************************************************** Disassembly of section .text:
080483d0 <_start>: 80483d0: 31 ed xor %ebp,%ebp 80483d2: 5e pop %esi 80483d3: 89 e1 mov %esp,%ecx 80483d5: 83 e4 f0 and $0xfffffff0,%esp 80483d8: 50 push %eax 80483d9: 54 push %esp 80483da: 52 push %edx 80483db: 68 70 85 04 08 push $0×8048570 80483e0: 68 00 85 04 08 push $0×8048500 80483e5: 51 push %ecx 80483e6: 56 push %esi 80483e7: 68 84 84 04 08 push $0×8048484 80483ec: e8 bf ff ff ff call 80483b0 <__libc_start_main@plt> 80483f1: f4 hlt 80483f2: 90 nop 80483f3: 90 nop 80483f4: 90 nop 80483f5: 90 nop 80483f6: 90 nop 80483f7: 90 nop 80483f8: 90 nop 80483f9: 90 nop 80483fa: 90 nop 80483fb: 90 nop 80483fc: 90 nop 80483fd: 90 nop 80483fe: 90 nop 80483ff: 90 nop
08048400 <__do_global_dtors_aux>: 8048400: 55 push %ebp 8048401: 89 e5 mov %esp,%ebp 8048403: 53 push %ebx 8048404: 83 ec 04 sub $0×4,%esp 8048407: 80 3d 1c a0 04 08 00 cmpb $0×0,0x804a01c 804840e: 75 3f jne 804844f <__do_global_dtors_aux+0x4f> 8048410: a1 20 a0 04 08 mov 0x804a020,%eax 8048415: bb 20 9f 04 08 mov $0x8049f20,%ebx 804841a: 81 eb 1c 9f 04 08 sub $0x8049f1c,%ebx 8048420: c1 fb 02 sar $0×2,%ebx 8048423: 83 eb 01 sub $0×1,%ebx 8048426: 39 d8 cmp %ebx,%eax 8048428: 73 1e jae 8048448 <__do_global_dtors_aux+0×48> 804842a: 8d b6 00 00 00 00 lea 0×0(%esi),%esi 8048430: 83 c0 01 add $0×1,%eax 8048433: a3 20 a0 04 08 mov %eax,0x804a020 8048438: ff 14 85 1c 9f 04 08 call *0x8049f1c(,%eax,4) 804843f: a1 20 a0 04 08 mov 0x804a020,%eax 8048444: 39 d8 cmp %ebx,%eax 8048446: 72 e8 jb 8048430 <__do_global_dtors_aux+0×30> 8048448: c6 05 1c a0 04 08 01 movb $0×1,0x804a01c 804844f: 83 c4 04 add $0×4,%esp 8048452: 5b pop %ebx 8048453: 5d pop %ebp 8048454: c3 ret 8048455: 8d 74 26 00 lea 0×0(%esi,%eiz,1),%esi 8048459: 8d bc 27 00 00 00 00 lea 0×0(%edi,%eiz,1),%edi
08048460 <frame_dummy>: 8048460: 55 push %ebp 8048461: 89 e5 mov %esp,%ebp 8048463: 83 ec 18 sub $0×18,%esp 8048466: a1 24 9f 04 08 mov 0x8049f24,%eax 804846b: 85 c0 test %eax,%eax 804846d: 74 12 je 8048481 <frame_dummy+0×21> 804846f: b8 00 00 00 00 mov $0×0,%eax 8048474: 85 c0 test %eax,%eax 8048476: 74 09 je 8048481 <frame_dummy+0×21> 8048478: c7 04 24 24 9f 04 08 movl $0x8049f24,(%esp) 804847f: ff d0 call *%eax 8048481: c9 leave 8048482: c3 ret 8048483: 90 nop
08048484 <main>: 8048484: 55 push %ebp 8048485: 89 e5 mov %esp,%ebp 8048487: 83 e4 f0 and $0xfffffff0,%esp 804848a: 83 ec 50 sub $0×50,%esp 804848d: 8b 45 0c mov 0xc(%ebp),%eax 8048490: 89 44 24 1c mov %eax,0x1c(%esp) 8048494: 65 a1 14 00 00 00 mov %gs:0×14,%eax 804849a: 89 44 24 4c mov %eax,0x4c(%esp) 804849e: 31 c0 xor %eax,%eax 80484a0: c7 44 24 28 00 00 00 movl $0×0,0×28(%esp) 80484a7: 00 80484a8: b8 d0 85 04 08 mov $0x80485d0,%eax 80484ad: 89 04 24 mov %eax,(%esp) 80484b0: e8 cb fe ff ff call 8048380 <printf@plt> 80484b5: b8 e8 85 04 08 mov $0x80485e8,%eax 80484ba: 8d 54 24 2c lea 0x2c(%esp),%edx 80484be: 89 54 24 04 mov %edx,0×4(%esp) 80484c2: 89 04 24 mov %eax,(%esp) 80484c5: e8 f6 fe ff ff call 80483c0 <__isoc99_scanf@plt> 80484ca: b8 eb 85 04 08 mov $0x80485eb,%eax 80484cf: 8d 54 24 2c lea 0x2c(%esp),%edx 80484d3: 89 54 24 04 mov %edx,0×4(%esp) 80484d7: 89 04 24 mov %eax,(%esp) 80484da: e8 a1 fe ff ff call 8048380 <printf@plt> 80484df: 8b 54 24 4c mov 0x4c(%esp),%edx 80484e3: 65 33 15 14 00 00 00 xor %gs:0×14,%edx 80484ea: 74 05 je 80484f1 <main+0x6d> 80484ec: e8 9f fe ff ff call 8048390 <__stack_chk_fail@plt> 80484f1: c9 leave 80484f2: c3 ret 80484f3: 90 nop 80484f4: 90 nop 80484f5: 90 nop 80484f6: 90 nop 80484f7: 90 nop 80484f8: 90 nop 80484f9: 90 nop 80484fa: 90 nop 80484fb: 90 nop 80484fc: 90 nop 80484fd: 90 nop 80484fe: 90 nop 80484ff: 90 nop
08048500 <__libc_csu_init>: 8048500: 55 push %ebp 8048501: 57 push %edi 8048502: 56 push %esi 8048503: 53 push %ebx 8048504: e8 69 00 00 00 call 8048572 <__i686.get_pc_thunk.bx> 8048509: 81 c3 eb 1a 00 00 add $0x1aeb,%ebx 804850f: 83 ec 1c sub $0x1c,%esp 8048512: 8b 6c 24 30 mov 0×30(%esp),%ebp 8048516: 8d bb 20 ff ff ff lea -0xe0(%ebx),%edi 804851c: e8 1b fe ff ff call 804833c <_init> 8048521: 8d 83 20 ff ff ff lea -0xe0(%ebx),%eax 8048527: 29 c7 sub %eax,%edi 8048529: c1 ff 02 sar $0×2,%edi 804852c: 85 ff test %edi,%edi 804852e: 74 29 je 8048559 <__libc_csu_init+0×59> 8048530: 31 f6 xor %esi,%esi 8048532: 8d b6 00 00 00 00 lea 0×0(%esi),%esi 8048538: 8b 44 24 38 mov 0×38(%esp),%eax 804853c: 89 2c 24 mov %ebp,(%esp) 804853f: 89 44 24 08 mov %eax,0×8(%esp) 8048543: 8b 44 24 34 mov 0×34(%esp),%eax 8048547: 89 44 24 04 mov %eax,0×4(%esp) 804854b: ff 94 b3 20 ff ff ff call *-0xe0(%ebx,%esi,4) 8048552: 83 c6 01 add $0×1,%esi 8048555: 39 fe cmp %edi,%esi 8048557: 75 df jne 8048538 <__libc_csu_init+0×38> 8048559: 83 c4 1c add $0x1c,%esp 804855c: 5b pop %ebx 804855d: 5e pop %esi 804855e: 5f pop %edi 804855f: 5d pop %ebp 8048560: c3 ret 8048561: eb 0d jmp 8048570 <__libc_csu_fini> 8048563: 90 nop 8048564: 90 nop 8048565: 90 nop 8048566: 90 nop 8048567: 90 nop 8048568: 90 nop 8048569: 90 nop 804856a: 90 nop 804856b: 90 nop 804856c: 90 nop 804856d: 90 nop 804856e: 90 nop 804856f: 90 nop
08048570 <__libc_csu_fini>: 8048570: f3 c3 repz ret
08048572 <__i686.get_pc_thunk.bx>: 8048572: 8b 1c 24 mov (%esp),%ebx 8048575: c3 ret 8048576: 90 nop 8048577: 90 nop 8048578: 90 nop 8048579: 90 nop 804857a: 90 nop 804857b: 90 nop 804857c: 90 nop 804857d: 90 nop 804857e: 90 nop 804857f: 90 nop
08048580 <__do_global_ctors_aux>: 8048580: 55 push %ebp 8048581: 89 e5 mov %esp,%ebp 8048583: 53 push %ebx 8048584: 83 ec 04 sub $0×4,%esp 8048587: a1 14 9f 04 08 mov 0x8049f14,%eax 804858c: 83 f8 ff cmp $0xffffffff,%eax 804858f: 74 13 je 80485a4 <__do_global_ctors_aux+0×24> 8048591: bb 14 9f 04 08 mov $0x8049f14,%ebx 8048596: 66 90 xchg %ax,%ax 8048598: 83 eb 04 sub $0×4,%ebx 804859b: ff d0 call *%eax 804859d: 8b 03 mov (%ebx),%eax 804859f: 83 f8 ff cmp $0xffffffff,%eax 80485a2: 75 f4 jne 8048598 <__do_global_ctors_aux+0×18> 80485a4: 83 c4 04 add $0×4,%esp 80485a7: 5b pop %ebx 80485a8: 5d pop %ebp 80485a9: c3 ret 80485aa: 90 nop 80485ab: 90 nop ************************************************************* 可以看出和我们自己解析的数据是完全匹配的。
第四部分:符号表(.symtab),数据如下: 01 00 00 00 //.symtab 02 00 00 00 //完整的符号表,它往往会包含很多在运行期间( 动态连接) 用不到的符号。 00 00 00 00 //flag 00 00 00 00 //因为没有重定位,地址为0 f4 15 00 00 //在gemfield文件中的偏移:0x15f4 30 04 00 00 //大小:0×0430 1d 00 00 00 //相关字符串表的节头索引 2d 00 00 00 //符号表中最后一个本地符号的索引值加1 04 00 00 00 //对齐 4个字节 10 00 00 00 //指向的是表(没错,符号表),每一个表项大小为0×10个字节。
数据摘录如下,地址范围为0x15f4~1a23,一共67项: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 54 81 04 08 00 00 00 00 03 00 01 00 00 00 00 00 68 81 04 08 00 00 00 00 03 00 02 00 00 00 00 00 88 81 04 08 00 00 00 00 03 00 03 00 00 00 00 00 ac 81 04 08 00 00 00 00 03 00 04 00 00 00 00 00 cc 81 04 08 00 00 00 00 03 00 05 00 00 00 00 00 3c 82 04 08 00 00 00 00 03 00 06 00 00 00 00 00 bc 82 04 08 00 00 00 00 03 00 07 00 00 00 00 00 cc 82 04 08 00 00 00 00 03 00 08 00 00 00 00 00 0c 83 04 08 00 00 00 00 03 00 09 00 00 00 00 00 14 83 04 08 00 00 00 00 03 00 0a 00 00 00 00 00 3c 83 04 08 00 00 00 00 03 00 0b 00 00 00 00 00 70 83 04 08 00 00 00 00 03 00 0c 00 00 00 00 00 d0 83 04 08 00 00 00 00 03 00 0d 00 00 00 00 00 ac 85 04 08 00 00 00 00 03 00 0e 00 00 00 00 00 c8 85 04 08 00 00 00 00 03 00 0f 00 00 00 00 00 04 86 04 08 00 00 00 00 03 00 10 00 00 00 00 00 38 86 04 08 00 00 00 00 03 00 11 00 00 00 00 00 14 9f 04 08 00 00 00 00 03 00 12 00 00 00 00 00 1c 9f 04 08 00 00 00 00 03 00 13 00 00 00 00 00 24 9f 04 08 00 00 00 00 03 00 14 00 00 00 00 00 28 9f 04 08 00 00 00 00 03 00 15 00 00 00 00 00 f0 9f 04 08 00 00 00 00 03 00 16 00 00 00 00 00 f4 9f 04 08 00 00 00 00 03 00 17 00 00 00 00 00 14 a0 04 08 00 00 00 00 03 00 18 00 00 00 00 00 1c a0 04 08 00 00 00 00 03 00 19 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 1a 00 01 00 00 00 00 00 00 00 00 00 00 00 04 00 f1 ff 0c 00 00 00 14 9f 04 08 00 00 00 00 01 00 12 00 1a 00 00 00 1c 9f 04 08 00 00 00 00 01 00 13 00 28 00 00 00 24 9f 04 08 00 00 00 00 01 00 14 00 35 00 00 00 00 84 04 08 00 00 00 00 02 00 0d 00 4b 00 00 00 1c a0 04 08 01 00 00 00 01 00 19 00 5a 00 00 00 20 a0 04 08 04 00 00 00 01 00 19 00 68 00 00 00 60 84 04 08 00 00 00 00 02 00 0d 00 01 00 00 00 00 00 00 00 00 00 00 00 04 00 f1 ff 74 00 00 00 18 9f 04 08 00 00 00 00 01 00 12 00 81 00 00 00 f8 86 04 08 00 00 00 00 01 00 11 00 8f 00 00 00 24 9f 04 08 00 00 00 00 01 00 14 00 9b 00 00 00 80 85 04 08 00 00 00 00 02 00 0d 00 b1 00 00 00 00 00 00 00 00 00 00 00 04 00 f1 ff b8 00 00 00 14 9f 04 08 00 00 00 00 00 00 12 00 c9 00 00 00 28 9f 04 08 00 00 00 00 01 00 15 00 d2 00 00 00 14 9f 04 08 00 00 00 00 00 00 12 00 e5 00 00 00 f4 9f 04 08 00 00 00 00 01 00 17 00 fb 00 00 00 70 85 04 08 02 00 00 00 12 00 0d 00 0b 01 00 00 72 85 04 08 00 00 00 00 12 02 0d 00 22 01 00 00 14 a0 04 08 00 00 00 00 20 00 18 00 2d 01 00 00 00 00 00 00 00 00 00 00 12 00 00 00 3f 01 00 00 1c a0 04 08 00 00 00 00 10 00 f1 ff 46 01 00 00 ac 85 04 08 00 00 00 00 12 00 0e 00 4c 01 00 00 00 00 00 00 00 00 00 00 12 00 00 00 68 01 00 00 20 9f 04 08 00 00 00 00 11 02 13 00 75 01 00 00 14 a0 04 08 00 00 00 00 10 00 18 00 82 01 00 00 00 00 00 00 00 00 00 00 20 00 00 00 91 01 00 00 18 a0 04 08 00 00 00 00 11 02 18 00 9e 01 00 00 cc 85 04 08 04 00 00 00 11 00 0f 00 ad 01 00 00 00 00 00 00 00 00 00 00 12 00 00 00 ca 01 00 00 00 85 04 08 61 00 00 00 12 00 0d 00 da 01 00 00 24 a0 04 08 00 00 00 00 10 00 f1 ff df 01 00 00 d0 83 04 08 00 00 00 00 12 00 0d 00 e6 01 00 00 c8 85 04 08 04 00 00 00 11 00 0f 00 ed 01 00 00 1c a0 04 08 00 00 00 00 10 00 f1 ff f9 01 00 00 84 84 04 08 6f 00 00 00 12 00 0d 00 fe 01 00 00 00 00 00 00 00 00 00 00 20 00 00 00 12 02 00 00 00 00 00 00 00 00 00 00 12 00 00 00 2c 02 00 00 3c 83 04 08 00 00 00 00 12 00 0b 00
符号表(symbol table) 所包含的信息用于定位和重定位程序中的符号定义和引用。目标文件的其它部分通过一个符号在这个表中的索引值来使用该符号。索引值从0 开始计数,但值为0 的表项(即第一项)并没有实际的意义,它表示未定义的符号。这里用常量STN_UNDEF 来表示未定义的符号。
一个符号表项的格式定义如下: typedef struct { Elf32_Word st_name; //符号的名字 Elf32_Addr st_value ; //符号的值 Elf32_Word st_size; //符号的大小 unsigned char st_info; unsigned char st_other ; Elf32_Half st_shndx ; } Elf32_Sym;//恰好16个字节
1、st_name,
符号的名字。但它并不是一个字符串,而是一个指向字符串表(.strtab)的索引值,在字符串表中对应位置上的字符串就是该符号名字的实际文本。如果此值为非0,它代表符号名在字符串 表中的索引值。如果此值为0,那么此符号无名字。
2、符号的值,
这个值其实没有固定的类型,它可能代表一个数值,也可以是一个地址,具体是什么要看上下文。对于不同的目标文件类型,符号表项的st_value 的含义略有不同:
*在重定位文件中,如果一个符号对应的节的索引值是SHN_COMMON,st_value 值是这个节内容的字节对齐数。 *在重定位文件中,如果一个符号是已定义的,那么它的st_value 值是该符号的起始地址在其所在节中的偏移量,而其所在的节的索引由st_shndx 给出。 *在可执行文件和共享库文件中,st_value 不再是一个节内的偏移量,而是一个虚拟地址,直接指向符号所在的内存位置。这种情况下,st_shndx就不再需要了。 如果一个可执行文件中含有一个函数的引用,而这个函数是定义在一个共享目标文件中,那么在可执行文件中,针对那个共享目标文件的符号表应该含有这个函数的符号。符号表的st_shndx 成员值为SHN_UNDEF ,这就告诉了动态连接器,这个函数的符号定义并不在可执行文件中。如果已经在可执行文件中给这个符号申请了一个函数连接表项,而且符号表项的st_value 成员不是 0,那么st_value值就将是函数连接表项中第一条指令的地址。否则,st_value 成员是0。这个函数连接表项地址被动态连接器用来解析函数地址。细节参见 http://civilnet.cn/bbs/topicno/71157 。
3、st_size,
符号的大小。各种符号的大小各不相同,比如一个对象的大小就是它实际占用的字节数。如果一个符号的大小为0 或者大小未知,则这个值为0。
4、st_info,
符号的类型和属性。st_info 由一系列的比特位构成,标识了“符号绑定(symbol binding) ”、“符号类型(symbol type) ”和“符号信息(symbol infomation)”三种属性。下面几个宏分 别用于读取这三种属性值。
#define ELF32_ST_BIND( i ) ((i)>>4) #define ELF32_ST_TYPE( i ) ((i)&0xf) #define ELF32_ST_INFO( b,t ) (((b)<<4)+((t)&0xf))
下面分别说明: 符号绑定(Symbol Binding) 属性由ELF32_ST_BIND指定。 名字 值 STB_LOCAL 0 STB_GLOBAL 1 STB_WEAK 2 STB_LOPROC 13 STB_HIPROC 15
STB_LOCAL 表明本符号是一个本地符号。它只出现在本文件中,在本文件外该符号无效。所以在不同的文件中可以定义相同的符号名,它们之间不会互相影响。
STB_GLOBAL 表明本符号是一个全局符号。当有多个文件被连接在一起时,在所有文件中该符号都是可见的。正常情况下,在一个文件中定义的全局符号,一定是在其它文件中需要被引用,否则无须定义为全局。 STB_WEAK 类似于全局符号,但是相对于STB_GLOBAL,它们的优先级更低。 全局符号(global symbol) 和弱符号(weak symbol) 在以下两方面有区别: *当连接编辑器把若干个可重定位目标文件连接起来时,同名的STB_GLOBAL 符号不允许出现多次。而如果在一个目标文件中已经定义了一个全局的符号(global symbol) ,当一个同名的弱符 号(weak symbol) 出现时,并不会发生错误。连接编辑器会以全局符号为准,忽略弱符号。与全局符号相似,如果已经存在的是一个公用符号,即st_shndx 域为SHN_COMMON值的符号,当一个同名的弱符号(weak symbol) 出现时,也不会发生错误。连接编辑器会以公用符号为准,忽略弱符号。
*在查找符号定义时,连接编辑器可能会搜索存档的库文件。如果是查找全局符号,连接编辑器会提取包含该未定义的全局符号的存档成员,存档成员可能是一个全局的符号,也可能是弱符号 ;而如果是查找弱符号,连接编辑器不会去提取存档成员。未解析的弱符号值为0。
STB_LOPROC ~ STB_HIPROC 为特殊处理器保留的属性区间。 在符号表中,不同属性的符号所在位置也有不同,本地符号(STB_LOCAL)排在前面,全局符号(STB_GLOBAL/STB_WEAK) 排在后面。 符号类型(Symbol Types) 属性由ELF32_ST_TYPE 指定:
名字 值 STT_NOTYPE 0 STT_OBJECT 1 STT_FUNC 2 STT_SECTION 3 STT_FILE 4 STT_LOPROC 13 STT_HIPROC 15
STT_NOTYPE 本符号类型未指定。 STT_OBJECT 本符号是一个数据对象,比如变量、数组等。 STT_FUNC 本符号是一个函数,或者其它的可执行代码。函数符号在共享目标文件中有特殊的意义。当另外一个目标文件引用一个共享目标文件中的函数符号时,连接编辑器为被引用符号自动创建一个连接表项。非STT_FUNC类型的共享目标符号不会通过这种连接表项被自动引用。 STT_SECTION 本符号与一个节相关联,用于重定位,通常具有STB_LOCAL 属性。 STT_FILE 本符号是一个文件符号,它具有STB_LOCAL 属性,它的节索引值是SHN_ABS。在符号表中如果存在本类符号的话,它会出现在所有STB_LOCAL 类符号的前部。 STT_LOPROC ~ STT_HIPROC 这一区间的符号类型为特殊处理器保留。
5、st_other, 本数据成员目前暂未使用,在目标文件中一律赋值为0。
6、st_shndx, 任何一个符号表项的定义都与某一个“节”相联系,因为符号是为节而定义,在节中被引用。本数据成员即指明了相关联的节。本数据成员是一个索引值,它指向相关联的节在节头表中的索引。在重定位过程中,节的位置会改变,本数据成员的值也随之改变,继续指向节的新位置。当本数据成员指向下面三种特殊的节索引值时,本符号具有如下特别的意义:
SHN_ABS 符号的值是绝对的,具有常量性,在重定位过程中,此值不需要改变。 SHN_COMMON 本符号所关联的是一个还没有分配的公共节,本符号的值规定了其内容的字节对齐规则,与sh_addralign相似。也就是说,连接器会为本符号分配存储空间,而且其起始地址是向st_value 对 齐的。本符号的值指明了要分配的字节数。 SHN_UNDEF 当一个符号指向第1 节(SHN_UNDEF) 时,表明本符号在当前目标文件中未定义,在连接过程中,连接器会找到此符号被定义的文件,并把这些文件连接在一起。本文件中对该符号的引用会被连接到实际的定义上去。