zoukankan      html  css  js  c++  java
  • 编译链接objdump教材2.3.1

    T1.c

      1 #include <stdio.h>
      2 int g = 1203;
      3 int h;
      4 static int s;
      5 
      6 int main(int argc,char *argv[]){
      7     int a = 1,b;
      8     static int c = 3;
      9     b = 2;
     10     c = mysum(a,b);
     11     printf("sum=%d
    ",c);
     12 }
    

    T2.c

      1 extern int g;
      2 int mysum(int x,int y){
      3     return x+y+g;
      4 }
    

    隐式声明和想要声明的函数一样,所以没出问题。
    但我觉得这样不好。


    网上学习objdump命令,提交不少于5篇博客链接和微信读书上的图书链接

    https://blog.csdn.net/q2519008/article/details/82349869
    https://linux265.com/course/linux-command-objdump.html
    https://www.cnblogs.com/baiduboy/p/7061365.html
    https://www.jianshu.com/p/a9a1d07302dc
    https://blog.csdn.net/weixin_43836778/article/details/90749138
    https://www.pianshen.com/article/3362131908/

    我认为最好的讲解资源的链接
    https://man.linuxde.net/objdump


    用objdump分析第1步中的可执行文件和目标文件,提交你的分析截图以及如何和教材讲解内容对应的
    比如obj文件的文件头,代码段,数据段等,可执行文件如何链接mysum的。

    可重定位目标文件中包含有很多的节,格式如下图:

    ELF头
    包括16字节的标识信息、文件类型(.o,exec,.so)、机器类型(如Intel 80386)、节头表的偏移、节头表的表项大小及表项个数。

    .text节
    编译后的代码部分。

    .rodata节
    只读数据,如 printf用到的格式串、switch跳转表等。

    .data节
    已初始化的全局变量和静态变量。

    .bss节
    未初始化全局变量和静态变量,仅是占位符,不占据任何磁盘空间。区分初始化和非初始化是为了空间效率。

    .symtab节
    存放函数和全局变量(符号表)的信息,它不包括局部变量。

    .rel.text节
    .text节的重定位信息,用于重新修改代码段的指令中的地址信息。

    .rel.data节
    .data节的重定位信息,用于对被模块使用或定义的全局变量进行重定位的信息。

    .debug节
    调试用的符号表(gcc -g)

    .strtab节
    包含 .symtab节和 .debug节中的符号及节名

    节头表(Section header table)
    包含每个节的节名在.strtab节中的偏移、节的偏移和节的大小.

    • 既然.obj文件中都没有存储.bss段的信息,那么在程序中那些初始化为0的全局变量和未初始化的局部变量它是怎么识别它们的?

    • 答:由于.bss段中都是0,所以不需要记录。只需要记录其大小即可,所以通过段表即可找到。

    链接过程

    将.o文件的各个段分别合并

    合并符号表,给符号分配正确的地址

    依据符号表中的记录替换编译时保留的无效地址(占位用的)

    可以看到编译过程并不给数据和函数入口分配内存地址,在.o文件中,由于无法确定具体的地址,此时编译器只是将其赋了一个特殊的地址0x0,然后在最后的链接阶段再完成正确的地址赋值。

    目标文件中的符号表

    目标文件的.symtab节记录着符号表信息,符号表示一个结构体数组,每个表项(16字节)的结构如下:

    符号解析:所有obj文件符号表中对符号引用的地方都要找到符号定义的地方,否则就会出现链接错误。由于源文件是单独编译的,所以对外部的符号处理为UND即undefine。

  • 相关阅读:
    linux c编程错误汇总
    linux 相对路径
    内存池版本4多线程可变大小对象的内存池
    2. D3DBlankWindow添加透视投影矩阵
    1. D3DBalnkWindow
    内存池版本3单线程可变大小对象的内存池
    内联函数提高程序性能
    代码优化
    STL总结
    内存池版本2单线程固定大小对象的内存池
  • 原文地址:https://www.cnblogs.com/cfqlovem-521/p/15487573.html
Copyright © 2011-2022 走看看