计算机系统基础 第七章 链接 技术日志一
所选择代码
main.c
/* main.c */
/* $begin main */
int sum(int *a, int n);
int array[2] = {1, 2};
int main()
{
int val = sum(array, 2);
return val;
}
/* $end main */
sum.c
/* sum.c */
/* $begin sum */
int sum(int *a, int n)
{
int i, s = 0;
for (i = 0; i < n; i++) {
s += a[i];
}
return s;
}
/* $end sum */
操作
-
gcc -c main.c sum.c
生成main.o sum.o文件 -
-h 查看ELF头
2.1 readelf -h main.o
查看main.o的ELF头
Magic:45 4c 46分别是E L F三个字母的ASCII码
Class(类别):格式为32位
Data(数据):补码表示,按小端方式存放
Version(版本):1
OS/ABI: 表示操作系统的类型 这里是UNIX - System V
Type:ELF文件类型为可重定位文件REL
Machine:在32位机器上编译的目标代码
程序入口地址为0,是可重定位的文件类型,是链接式,不是执行式,不可运行
程序头起点:没有程序头表,偏移量为0
节头表起始位置:起始地址为284字节
本头的大小:ELF(这个头)节头大小为52字节
程序头大小:0
程序头的数目:0
节头大小:40字节
节头数量:12个表项
字符串表索引节头:节头表中第9项是字符串表
2.2 readelf -h sum.o查看sum.oELF头
与main.o的ELF头相类似
2.3 readelf -h prog
查看可执行文件prog的ELF头
区别:
Type:ELF文件类型为可执行文件EXEC
程序入口地址为0x80482f0,是可执行的文件类型
程序头起点:偏移量为52
程序头大小:32B
-
-S查看节头表
3.1 readelf -S main.o
读取main.o中节头表
该节头表一共有12个节的信息,起始位置在0x11c处
Addr 每一节起始地址都是零,因为该文件是可重定位目标文件,是链接视图不是执行视图
每一表项40B
.text 自000034位置开始,大小为27
.rel.text自0003c4位置开始,大小为10
.data自00005c位置开始,大小为8
.bss自000064位置开始,大小为0
.comment 自000064位置开始,大小为25
.note.GNU-stack 自000089位置开始,大小为0
.eh_frame 自00008c位置开始,大小为38
.rel.eh_frame 自0003d4位置开始,大小为8
.shstrtab 自0000c4位置开始,大小为57
.symtab 自0002fc位置开始,大小为b0
.strtab自0003ac位置开始,大小为17可重定位目标文件main.o的结构
000000 | ELF头占0x34B,节头表从00011c开始 34 |
---|---|
000034 | .text 27 |
00005b | - |
00005c | .data 8 |
000064 | .bss .comment 25 |
000089 | .note.GNU-stack |
???找不到 | ??? |
0000c4 | .shstrtab 57 |
00011b | - |
00011c | 节头表 1240=480=0x1e0* |
0002fc | .symtab b0 |
0003ac | .strtab 17 |
… | … |
3.2 readelf -S prog
查看可执行文件prog节头表
- -s查看符号
readelf -s main.o
array是main.o中第三节(.data)的符号,是全局变量,占8B,符号类型OBJECT
main是第一节(.text)的符号,是全局函数,占39B
sum是未定义的符号,不知道类型和大小,全局的(在其他模块定义)
注:学习用,借鉴中国大学MOOC南京大学袁春风老师《计算机系统基础》网课