第2部分 静态链接---(4)静态链接
来源:互联网 发布:程序员论坛排行榜 编辑:程序博客网 时间:2024/06/05 04:05
#################
# 4、静态链接
#################
// a.cextern int shared;int main(){ int a = 100; swap(&a, &shared);}
// b.cint shared = 1;void swap(int *a, int *b){ *a ^= *b ^= *a ^= *b;}
// a.c中定义了一个全局符号main// b.c中定义了两个全局符号,变量shared和swap// 模块a.c里面引用到了b.c里面的swap和shared,所以需要把a.o和b.o链接在一起形成最后的可执行文件ab$ gcc -c a.c b.c // 编译成目标文件a.o 和 b.o$ ld a.o b.o -e main -o ab // -e main 表示将main函数作为程序入口,ld链接器默认的程序入口为_start,-o指定输出的文件名,默认为a.out
空间与地址分配
相似段合并:将所有输入文件的.text合并到输出文件的.text段,接着是.data段、.bss段等。
整个链接过程分两步:
(1)空间与地址分配:扫描所有的输入目标文件,获取它们的各个段的长度、属性和位置,并且将输入目标文件中的符号表中所有的符号定义和符号引用收集起来,统一放到一个全局符号表。
(2)符号解析与重定位:使用上面第一步中收集到的所有信息,读取输入文件中段的数据、重定位信息,并且进行符号解析与重定位、调整代码中的地址等。
[xiaoloaw@AONT03 partTwo]$ objdump -h a.oa.o: file format elf32-i386Sections:Idx Name Size VMA LMA File off Algn 0 .text 00000027 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000000 00000000 00000000 0000005c 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000000 00000000 00000000 0000005c 2**2 ALLOC 3 .comment 0000002e 00000000 00000000 0000005c 2**0 CONTENTS, READONLY 4 .note.GNU-stack 00000000 00000000 00000000 0000008a 2**0 CONTENTS, READONLY[xiaoloaw@AONT03 partTwo]$[xiaoloaw@AONT03 partTwo]$ objdump -h b.ob.o: file format elf32-i386Sections:Idx Name Size VMA LMA File off Algn 0 .text 0000003a 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .data 00000004 00000000 00000000 00000070 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000000 00000000 00000000 00000074 2**2 ALLOC 3 .comment 0000002e 00000000 00000000 00000074 2**0 CONTENTS, READONLY 4 .note.GNU-stack 00000000 00000000 00000000 000000a2 2**0 CONTENTS, READONLY[xiaoloaw@AONT03 partTwo]$[xiaoloaw@AONT03 partTwo]$ objdump -h abab: file format elf32-i386Sections:Idx Name Size VMA LMA File off Algn 0 .text 00000062 08048094 08048094 00000094 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .data 00000004 080490f8 080490f8 000000f8 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .comment 0000002d 00000000 00000000 000000fc 2**0 CONTENTS, READONLY[xiaoloaw@AONT03 partTwo]$[xiaoloaw@AONT03 partTwo]$[xiaoloaw@AONT03 partTwo]$ ld a.o b.o -e main -o ab[xiaoloaw@AONT03 partTwo]$ objdump -h a.oa.o: file format elf32-i386Sections:Idx Name Size VMA LMA File off Algn 0 .text 00000027 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000000 00000000 00000000 0000005c 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000000 00000000 00000000 0000005c 2**2 ALLOC 3 .comment 0000002e 00000000 00000000 0000005c 2**0 CONTENTS, READONLY 4 .note.GNU-stack 00000000 00000000 00000000 0000008a 2**0 CONTENTS, READONLY[xiaoloaw@AONT03 partTwo]$ objdump -h b.ob.o: file format elf32-i386Sections:Idx Name Size VMA LMA File off Algn 0 .text 0000003a 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .data 00000004 00000000 00000000 00000070 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000000 00000000 00000000 00000074 2**2 ALLOC 3 .comment 0000002e 00000000 00000000 00000074 2**0 CONTENTS, READONLY 4 .note.GNU-stack 00000000 00000000 00000000 000000a2 2**0 CONTENTS, READONLY[xiaoloaw@AONT03 partTwo]$[xiaoloaw@AONT03 partTwo]$[xiaoloaw@AONT03 partTwo]$ objdump -h abab: file format elf32-i386Sections:Idx Name Size VMA LMA File off Algn 0 .text 00000062 08048094 08048094 00000094 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .data 00000004 080490f8 080490f8 000000f8 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .comment 0000002d 00000000 00000000 000000fc 2**0 CONTENTS, READONLY
[xiaoloaw@AONT03 partTwo]$ objdump -d a.o // -d 查看a.o 的代码段反汇编结果a.o: file format elf32-i386Disassembly of section .text:00000000 <main>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 e4 f0 and $0xfffffff0,%esp 6: 83 ec 20 sub $0x20,%esp 9: c7 44 24 1c 64 00 00 movl $0x64,0x1c(%esp) 10: 00 11: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) 18: 00 19: 8d 44 24 1c lea 0x1c(%esp),%eax 1d: 89 04 24 mov %eax,(%esp) 20: e8 fc ff ff ff call 21 <main+0x21> 25: c9 leave 26: c3 ret [xiaoloaw@AONT03 partTwo]$
[xiaoloaw@AONT03 partTwo]$ objdump -d abab: file format elf32-i386Disassembly of section .text:08048094 <main>: 8048094: 55 push %ebp 8048095: 89 e5 mov %esp,%ebp 8048097: 83 e4 f0 and $0xfffffff0,%esp 804809a: 83 ec 20 sub $0x20,%esp 804809d: c7 44 24 1c 64 00 00 movl $0x64,0x1c(%esp) 80480a4: 00 80480a5: c7 44 24 04 f8 90 04 movl $0x80490f8,0x4(%esp) 80480ac: 08 80480ad: 8d 44 24 1c lea 0x1c(%esp),%eax 80480b1: 89 04 24 mov %eax,(%esp) 80480b4: e8 03 00 00 00 call 80480bc <swap> 80480b9: c9 leave 80480ba: c3 ret 80480bb: 90 nop080480bc <swap>: 80480bc: 55 push %ebp 80480bd: 89 e5 mov %esp,%ebp 80480bf: 53 push %ebx 80480c0: 8b 45 08 mov 0x8(%ebp),%eax 80480c3: 8b 10 mov (%eax),%edx 80480c5: 8b 45 0c mov 0xc(%ebp),%eax 80480c8: 8b 08 mov (%eax),%ecx 80480ca: 8b 45 08 mov 0x8(%ebp),%eax 80480cd: 8b 18 mov (%eax),%ebx 80480cf: 8b 45 0c mov 0xc(%ebp),%eax 80480d2: 8b 00 mov (%eax),%eax 80480d4: 31 c3 xor %eax,%ebx 80480d6: 8b 45 08 mov 0x8(%ebp),%eax 80480d9: 89 18 mov %ebx,(%eax) 80480db: 8b 45 08 mov 0x8(%ebp),%eax 80480de: 8b 00 mov (%eax),%eax 80480e0: 31 c1 xor %eax,%ecx 80480e2: 8b 45 0c mov 0xc(%ebp),%eax 80480e5: 89 08 mov %ecx,(%eax) 80480e7: 8b 45 0c mov 0xc(%ebp),%eax 80480ea: 8b 00 mov (%eax),%eax 80480ec: 31 c2 xor %eax,%edx 80480ee: 8b 45 08 mov 0x8(%ebp),%eax 80480f1: 89 10 mov %edx,(%eax) 80480f3: 5b pop %ebx 80480f4: 5d pop %ebp 80480f5: c3 ret查看重定位表
[xiaoloaw@AONT03 partTwo]$ objdump -r a.oa.o: file format elf32-i386RELOCATION RECORDS FOR [.text]:OFFSET TYPE VALUE00000015 R_386_32 shared00000021 R_386_PC32 swap符号解析
[xiaoloaw@AONT03 partTwo]$ ld a.old: warning: cannot find entry symbol _start; defaulting to 0000000008048074a.o: In function `main':a.c:(.text+0x15): undefined reference to `shared'a.c:(.text+0x21): undefined reference to `swap'查看a.o的符号表
[xiaoloaw@AONT03 partTwo]$ readelf -s a.oSymbol table '.symtab' contains 10 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FILE LOCAL DEFAULT ABS a.c 2: 00000000 0 SECTION LOCAL DEFAULT 1 3: 00000000 0 SECTION LOCAL DEFAULT 3 4: 00000000 0 SECTION LOCAL DEFAULT 4 5: 00000000 0 SECTION LOCAL DEFAULT 6 6: 00000000 0 SECTION LOCAL DEFAULT 5 7: 00000000 39 FUNC GLOBAL DEFAULT 1 main 8: 00000000 0 NOTYPE GLOBAL DEFAULT UND shared 9: 00000000 0 NOTYPE GLOBAL DEFAULT UND swapar工具查看文件中包含哪些目标文件
[xiaoloaw@AONT03 lib]$ pwd/usr/lib/i686-redhat-linux5E/lib[xiaoloaw@AONT03 lib]$ ar -t libc.ainit-first.olibc-start.osysdep.oversion.ocheck_fds.olibc-tls.oelf-init.odso_handle.oerrno.oerrno-loc.ohp-timing.oiconv_open.oiconv.oiconv_close.ogconv_open.ogconv.ogconv_close.ogconv_db.o...objdump查看libc.a的符号
[xiaoloaw@AONT03 lib]$ objdump -t libc.a | grep "printf"最"小"的程序
// TinyHelloWorld.cchar *str = "Hello world!\n";void print(){ asm( "movl $13, %%edx \n\t" "movl %0, %%ecx \n\t" "movl $0, %%ebx \n\t" "movl $4, %%eax \n\t" "int $0x80 \n\t" ::"r"(str):"edx", "ecx", "ebx" );}void exit(){ asm( "movl $42,%ebx \n\t" "movl $1,%eax \n\t" "int $0x80 \n\t" );}void nomain(){ print(); exit();
[xiaoloaw@AONT03 partTwo]$ gcc -c -fno-builtin TinyHelloWorld.c // GCC编译器提供了很多内置函数,它会把一些常用的C库函数替换成编译器的内置函数,达到优化的功能。-fno-builtin参数关闭GCC内置函数功能。[xiaoloaw@AONT03 partTwo]$ ld -static -e nomain -o TinyHelloWorld TinyHelloWorld.o // 使用静态链接方式来链接程序,而不是使用默认的动态链接方式。[xiaoloaw@AONT03 partTwo]$ ./TinyHelloWorldHello world![xiaoloaw@AONT03 partTwo]$ echo $?42
阅读全文
0 0
- 第2部分 静态链接---(4)静态链接
- 第2部分 静态链接---(2)编译与链接
- 【静态链接】第2章---------------------静态链接过程(静态库链接)
- 第2部分 静态链接---(3)目标文件里有什么
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- sql server2012 使用IP地址登录服务器的配置
- 简单理解python中的装饰器
- 每天一个linux命令:grep 命令
- web调用手机相册和拍照
- Redis 配置文件详解
- 第2部分 静态链接---(4)静态链接
- jsp基础
- 将Java程序注册成系统服务
- 1524--回文串判定
- TP搜索,分页(保留搜索条件)简单实现
- mysql 完整性约束条件
- Java通过SMS平台实现短信发送功能(不看后悔)
- android 实现点击edittext的“小眼睛”切换明密文
- anaconda下matplotlib画散点图、柱形图、折线图、饼图