免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2713 | 回复: 5
打印 上一主题 下一主题

why ld accepts a single .o as the least unit for linking? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-03-25 21:20 |只看该作者 |倒序浏览
eg:
1.c contains:
main()
{
      f1();
}

2.c contains:
f1(){}
f2(){}

gcc 1.c 2.c
a.out contains code segment from 2.o even though f2() is not invoked by main().
can ld accept a function or global variable as the least linking input unit?

thanks in advance and sorry for english, i can't type chinese now...

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2008-03-29 09:49 |只看该作者
ld script

论坛徽章:
0
3 [报告]
发表于 2008-03-30 19:16 |只看该作者
ld 的操作单位是section,因为重定位的时候也是按section来的,而不是按照 function, 那么太麻烦了。 如非要给一个函数单独排,可以使用 attribute 语法将函数放到一个特定的section中,然后去排这个section 就可以了

论坛徽章:
0
4 [报告]
发表于 2008-03-31 01:37 |只看该作者
实验1:
filename: 1.c

extern int max(int x, int y);

int main()
{
    max(1, 2);

    return 0;
}


filename: 2.c

int max(int x, int y)
{
    return (x)>(y)? (x): (y);
}

int min(int x, int y)
{
    return (x)<(y)? (x): (y);
}


[everytime@localhost ld_study]$ gcc -v 1.c 2.c
使用内建 specs。
目标:i386-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux
线程模型:posix
gcc 版本 4.1.2 20070925 (Red Hat 4.1.2-33)
/usr/libexec/gcc/i386-redhat-linux/4.1.2/cc1 -quiet -v 1.c -quiet -dumpbase 1.c -mtune=generic -auxbase 1 -version -o /tmp/ccs4uRsk.s
忽略不存在的目录“/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/include”
#include "..." 搜索从这里开始:
#include <...> 搜索从这里开始:
/usr/local/include
/usr/lib/gcc/i386-redhat-linux/4.1.2/include
/usr/include
搜索列表结束。
GNU C 版本 4.1.2 20070925 (Red Hat 4.1.2-33) (i386-redhat-linux)
        由 GNU C 版本 4.1.2 20070925 (Red Hat 4.1.2-33) 编译。
GGC 准则:--param ggc-min-expand=98 --param ggc-min-heapsize=128202
Compiler executable checksum: ab322ce5b87a7c6c23d60970ec7b7b31
as -V -Qy -o /tmp/ccGOPQ7x.o /tmp/ccs4uRsk.s
GNU assembler version 2.17.50.0.18 (i386-redhat-linux) using BFD version version 2.17.50.0.18-1 20070731
/usr/libexec/gcc/i386-redhat-linux/4.1.2/cc1 -quiet -v 2.c -quiet -dumpbase 2.c -mtune=generic -auxbase 2 -version -o /tmp/ccs4uRsk.s
忽略不存在的目录“/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/include”
#include "..." 搜索从这里开始:
#include <...> 搜索从这里开始:
/usr/local/include
/usr/lib/gcc/i386-redhat-linux/4.1.2/include
/usr/include
搜索列表结束。
GNU C 版本 4.1.2 20070925 (Red Hat 4.1.2-33) (i386-redhat-linux)
        由 GNU C 版本 4.1.2 20070925 (Red Hat 4.1.2-33) 编译。
GGC 准则:--param ggc-min-expand=98 --param ggc-min-heapsize=128202
Compiler executable checksum: ab322ce5b87a7c6c23d60970ec7b7b31
as -V -Qy -o /tmp/ccuRCiKK.o /tmp/ccs4uRsk.s
GNU assembler version 2.17.50.0.18 (i386-redhat-linux) using BFD version version 2.17.50.0.18-1 20070731
/usr/libexec/gcc/i386-redhat-linux/4.1.2/collect2 --eh-frame-hdr --build-id -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbegin.o -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.. /tmp/ccGOPQ7x.o /tmp/ccuRCiKK.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i386-redhat-linux/4.1.2/crtend.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o

[everytime@localhost ld_study]$ objdump -j .text -S a.out >dump_file
......省略......
129 080483e9 <min>:
130  80483e9:   55                      push   %ebp
131  80483ea:   89 e5                   mov    %esp,%ebp
132  80483ec:   83 ec 08                sub    $0x8,%esp
133  80483ef:   8b 45 08                mov    0x8(%ebp),%eax
134  80483f2:   89 45 f8                mov    %eax,-0x8(%ebp)
135  80483f5:   8b 45 0c                mov    0xc(%ebp),%eax
136  80483f8:   89 45 fc                mov    %eax,-0x4(%ebp)
137  80483fb:   8b 45 f8                mov    -0x8(%ebp),%eax
138  80483fe:   39 45 fc                cmp    %eax,-0x4(%ebp)
139  8048401:   7e 06                   jle    8048409 <min+0x20>
140  8048403:   8b 45 f8                mov    -0x8(%ebp),%eax
141  8048406:   89 45 fc                mov    %eax,-0x4(%ebp)
142  8048409:   8b 45 fc                mov    -0x4(%ebp),%eax
143  804840c:   c9                      leave


实验2:
filename:1.c

extern int max(int x, int y);

int main()
{
    max(1, 2);

    return 0;
}

filename:2.c

int max(int x, int y)
{
    return (x)>(y)? (x): (y);
}


filename:3.c

int min(int x, int y)
{
    return (x)<(y)? (x): (y);
}


[everytime@localhost ld_study]$ gcc -c 2.c 3.c
[everytime@localhost ld_study]$ ar rcs libtest.a 2.o 3.o
[everytime@localhost ld_study]$ gcc -c 1.c
[everytime@localhost ld_study]$ gcc -static -o ldstudy 1.o libtest.a
[everytime@localhost ld_study]$ objdump -j .text -S ldstudy >dump_file
不包含min()了

关于原因,请参考《深入理解计算机系统》7.6.3 链接器如何使用静态库来解析引用
今天晚上刚好看到这一章,还有很多问题不懂,囫囵吞枣中

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
5 [报告]
发表于 2008-03-31 12:42 |只看该作者
确实也只能曲线救国,呵呵

论坛徽章:
0
6 [报告]
发表于 2008-03-31 16:21 |只看该作者
C语言可以把所有的执行代码分成一个个的函数.
到汇编层就做不到了.
汇编(或者说机器码)不是基于函数的语言.
汇编器没有办法区分普通的标号和函数名,也没办法识别函数体.
直接做是不可能的,如果要求gcc做这样的识别,倒是有可能做到.

曲线救国........好名字
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP