编译静态libc C代码和ASM代码 [英] Compiling statically libc C code and ASM code

查看:233
本文介绍了编译静态libc C代码和ASM代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有ASM代码:

  extern my_func 
extern printf
extern exit
全局_开始
章节.data
...
章节.text
_start:
...
调用printf
...
调用my_func
...
调用出口

和C代码:

  int my_func(int a,int b)
{
return a + b;
}

我在64位机器上使用fedora。我想要的可执行文件是32位。
对于动态链接,我这样做:

  nasm -f elf32 asm.asm;这给了我asm.o 
gcc -m32 -Wall -c c_code.c;这给了我c_code.o
ld c_code.o asm.o -melf_i386 -L / usr / lib / -lc -I /lib/ld-linux.so.2;这给我a.out运行良好,权重5601字节。

我想要做的是静态链接libc。我做了以下工作:

  gcc -o a2.out -m32 -static -m32 asm.o c_code.o 

我得到错误:

  asm.o:函数`_start':
asm.asm :(。text + 0x0):`_start'的多重定义
/ usr / lib / gcc / x86_64-redhat -linux / 4.8.3 /../../../../ lib64 / crt1.o :( .text + 0x0):
首先在这里定义
collect2:error:ld returned 1退出状态

然后,我将_start更改为ASM代码中的主体,整个链接都很好! ldd显示不是动态可执行文件。但该文件创建了权重721067字节!我认为它会静态编译大量不必要的代码。
所以,我的第一个问题是:
$ b $ 1)如何才能静态链接所需的printf函数和退出函数的libc?



当我尝试时

  gcc -m32 -o a3.out -lc asm.o c_code。 o; ASM文件具有main而不是_start 

我得到一个重量为7406字节的文件。 ldd显示与a.out相同的动态库,它加权5601字节。

2)为什么这种差异?看起来像一些额外的代码,连接_start与main在我的代码...
3)与gcc和ld连接有什么区别?




解决方案


1)如何静态链接libc需要printf
并退出函数?

尝试使用 -nostartfiles -static -nostdlib -lc进行编译这将避免添加crt1.o和crtend.o。但请记住,这将禁用所有Glibc初始化代码,因此一些Glibc函数将无法工作。


2)为什么这种差异?看起来像一些额外的代码
,连接_start与我的代码中的主...

GCC添加启动文件 crt * .o )执行初始化。有关详细信息,请参阅许多在线文章(例如这一篇)。


<3>与gcc和ld链接有什么不同?

已经在上面做了回答,但是通常你可以运行 gcc -v 并检查ld(或者collect2的)参数。


I have ASM code:

    extern my_func
    extern printf
    extern exit
    global _start
section .data
    ...
section .text
  _start:
    ...
    call printf
    ...
    call my_func
    ...
    call exit

and C code:

    int my_func(int a, int b)
    {
        return a+b;
    }

I'm using fedora on 64-bit machine. I want the executable be 32-bit. For dynamic linking I do:

nasm -f elf32 asm.asm ; this gives me asm.o
gcc -m32 -Wall -c c_code.c ; this gives me c_code.o
ld c_code.o asm.o -melf_i386 -L /usr/lib/ -lc -I /lib/ld-linux.so.2 ; this gives me a.out which runs fine and weights 5601 bytes.

What I want to do is link libc statically. I do the following:

gcc -o a2.out -m32 -static -m32 asm.o c_code.o

And I get error:

asm.o: In function `_start':
asm.asm:(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crt1.o:(.text+0x0):
first defined here       
collect2: error: ld returned 1 exit status

Then I change _start to main in ASM code and the whole thing links fine! ldd shows "not a dynamic executable". But the file created weights 721067 bytes! I think that it compiles statically a lot of unnecessary code. So, my 1st question is:

1) How can I link statically only libc for the required printf and exit functions?

When I try

gcc -m32 -o a3.out -lc asm.o c_code.o ; ASM file has main instead of _start

I get a file that weights 7406 bytes. ldd shows the same dynamic libraries as for the a.out which weights 5601 bytes.

2) Why is that difference? Looks like some additional code that "connects" _start with main in my code... 3) What is the difference between linking with gcc and ld?

Thanks a lot for your attention!

解决方案

1) How can I link statically only libc for the required printf and exit functions?

Try compiling with -nostartfiles -static -nostdlib -lc which will avoid adding crt1.o and crtend.o. But keep in mind that this will disable all Glibc initialization code so some Glibc functions will fail to work.

2) Why is that difference? Looks like some additional code that "connects" _start with main in my code...

GCC adds start files (crt*.o) which perform initialization. See the many online articles for details (e.g. this one).

3) What is the difference between linking with gcc and ld?

Already answered above but in general you can run gcc -v and inspect ld's (or collect2's) arguments.

这篇关于编译静态libc C代码和ASM代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆