// a.c
extern int shared;
int main() {
int a = 100;
swap(&a, &shared);
}
// b.c
int shared = 1;
void swap(int* a, int* b) {
*a ^= *b ^= *a ^= *b;
}
$ gcc -c a.c b.c -fno-stack-protector
a.c: In function ‘main’:
a.c:4:5: warning: implicit declaration of function ‘swap’ [-Wimplicit-function-declaration]
4 | swap(&a, &shared);
| ^~~~
// -e 表示将main函数作为程序的入口,ld连接器默认的程序入口为_start
$ ld a.o b.o -e main -o ab
ld: a.o: in function `main':
a.c:(.text+0x4f): undefined reference to `__stack_chk_fail'
// 解决方法参考 https://blog.csdn.net/wuqindeyunque/article/details/131593357
分配的概念:
分配方法:
使用第二种方法的链接器一般采用两部链接
$ objdump -h a.o
a.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000032 0000000000000000 0000000000000000 00000040 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 00000072 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 00000072 2**0
ALLOC
$ objdump -h b.o
b.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000004f 0000000000000000 0000000000000000 00000040 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000004 0000000000000000 0000000000000000 00000090 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 00000094 2**0
ALLOC
$ objdump -h ab
ab: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
1 .text 00000081 0000000000401000 0000000000401000 00001000 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
3 .data 00000004 0000000000404000 0000000000404000 00003000 2**2
CONTENTS, ALLOC, LOAD, DATA
重定位:会将符合的地址用一个假的临时地址地替代,真正地址的计算留给了链接器;
每一个ELF文件包含一个重定位表:
对于32位Intel X86 系列处理器,重定位表的结构是由下面结构数组定义,每个元素代表一个重定位入口
typedef struct {
Elf32_Addr r_offset; // 重定位入口的偏移
Elf32_Word r_info; // 重定位入口的类型和符号,低8位代表类型,高24位代表符号在符号表中的下标
} Elf32_Rel;
$ objdump -r a.o
a.o: file format elf64-x86-64
RELOCATION RECORDS FOR [.text]: # 代表代码段的重定位表
OFFSET TYPE VALUE
000000000000001a R_X86_64_PC32 shared-0x0000000000000004
0000000000000027 R_X86_64_PLT32 swap-0x0000000000000004
$ objdump -d a.o
a.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 :
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: 48 83 ec 10 sub $0x10,%rsp
c: c7 45 fc 64 00 00 00 movl $0x64,-0x4(%rbp)
13: 48 8d 45 fc lea -0x4(%rbp),%rax
17: 48 8d 35 00 00 00 00 lea 0x0(%rip),%rsi # 1e
1e: 48 89 c7 mov %rax,%rdi
21: b8 00 00 00 00 mov $0x0,%eax
26: e8 00 00 00 00 callq 2b
2b: b8 00 00 00 00 mov $0x0,%eax
30: c9 leaveq
31: c3 retq
$ objdump -d ab
ab: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 :
401000: f3 0f 1e fa endbr64
401004: 55 push %rbp
401005: 48 89 e5 mov %rsp,%rbp
401008: 48 83 ec 10 sub $0x10,%rsp
40100c: c7 45 fc 64 00 00 00 movl $0x64,-0x4(%rbp)
401013: 48 8d 45 fc lea -0x4(%rbp),%rax
401017: 48 8d 35 e2 2f 00 00 lea 0x2fe2(%rip),%rsi # 404000
40101e: 48 89 c7 mov %rax,%rdi
401021: b8 00 00 00 00 mov $0x0,%eax
401026: e8 07 00 00 00 callq 401032
40102b: b8 00 00 00 00 mov $0x0,%eax
401030: c9 leaveq
401031: c3 retq
0000000000401032 :
401032: f3 0f 1e fa endbr64
401036: 55 push %rbp
...