2017-01-10 4 views
0

У меня есть ASM код:Компиляция статически LibC C код и ASM код

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

и код C:

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

Я использую фетровую на 64-битной машине. Я хочу, чтобы исполняемый файл был 32-битным. Для динамической компоновки я:

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. 

То, что я хочу сделать, это ссылка Libc статически. Я делаю следующее:

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

И я получаю ошибку:

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 

Тогда я меняю _start на главную в ASM код и все это ссылки хорошо! ldd показывает «не динамический исполняемый файл». Но файл создал весы 721067 байт! Я думаю, что он собирает статически много ненужного кода. Итак, мой первый вопрос:

1) Как я могу связать статически только libc для требуемых функций printf и выхода?

Когда я пытаюсь

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

я получаю, что вес 7406 байт. ldd показывает те же динамические библиотеки, что и для a.out, который весит 5601 байт.

2) Почему это различие? Похож на какой-то дополнительный код, который «соединяет» _start с основным в моем коде ... 3) В чем разница между ссылкой на gcc и ld?

Большое спасибо за внимание!

ответ

0

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

Try компиляции с -nostartfiles -static -nostdlib -lc, который позволит избежать добавления crt1.o и crtend.o. Но имейте в виду, что это отключит весь код инициализации Glibc, поэтому некоторые функции Glibc не сработают.

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

GCC добавляет файлы запуска (crt*.o), которые выполняют инициализацию. Подробнее см. В многочисленных онлайн-статьях (например, this one).

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

Уже ответил выше, но в целом вы можете запустить gcc -v и проверить (или collect2'S) аргументы Л.Д..

+0

Спасибо! -nostartfiles уменьшает размер до 5749 байт. Но ldd все еще показывает libc.so.6, что означает, что libc по-прежнему связан динамически. – alexeik

+0

@alexeik Также передайте '-nostdlib'. – fuz

+0

Извините, не заметил статическую часть, обновленный ответ. – yugr

Смежные вопросы