Как правильно связать ассемблерный код с кодом C, используя gcc? - PullRequest
0 голосов
/ 05 мая 2018

Предположим, у вас есть следующие файлы сборки:

  .file "print.s"
  .intel_syntax noprefix

  .text

  .globl _start
  .type _start, @function
_start:
  mov rax, 1
  mov rdi, 1
  lea rsi, hello_string
  mov rdx, 14
  syscall
  mov rax, 60
  mov rdi, 0
  syscall
  .size _start, .-_start

и

  .file "string.s"
  .intel_syntax noprefix

  .data

  .globl hello_string
  .type hello_string, @object
hello_string:
  .string "Hello, world!\n"
  .size hello_string, 14

Если вы запустите as string.s -o string.o, as print.s -o print.o, а затем ld *.o -o hello.elf, вы получите исполняемый файл, который печатает Hello, world !. Теперь предположим, что вы изменили метку _start в print.s на print, и у вас есть следующий файл C:

// main.c
void print(void);

int main (void) {
  print();
  return 0;
}

Я хочу запустить что-то вроде gcc -o main.elf main.c string.s print.s, чтобы взять два моих файла сборки и связать их со стандартной средой выполнения C. Эта команда, как написано, не работает. Я получаю следующее сообщение об ошибке:

/usr/bin/ld: /tmp/ccc1yRif.o: relocation R_X86_64_32S against symbol `hello_string' can not be used when making a shared object; recompile with -fPIC

Я не могу понять, как правильно использовать флаг -fPIC, чтобы все заработало. Я даже не уверен, что это то, что я должен делать. Я мог бы попытаться использовать встроенный ассемблер, чтобы сделать это, но для моих реальных случаев использования это было бы крайне раздражающим, и я бы предпочел научиться правильно связывать куски сборки в мои программы на Си. Я не смог найти много информации об этом онлайн.

Вопрос: Как правильно использовать компоновщик GNU для привязки файлов сборки к среде выполнения C?

РЕДАКТИРОВАТЬ: В Как связать объектный файл C с объектным файлом на языке ассемблера? , ОП спрашивает о том, как решить аналогичную проблему связывания, просто используя ld. Я хочу использовать gcc, который является рекомендуемым решением в связанном вопросе, но я даже не могу заставить это работать.

1 Ответ

0 голосов
/ 05 мая 2018

ОК, так что я понял это сейчас. Кажется, сообщение об ошибке говорит мне, что gcc пытается создать общий объект. Это привело меня к вопросу gcc 6.2.0 пытается создать общий объект, когда это не нужно?

Решение - запустить gcc -no-pie main.c string.s print.s -o main.elf

в соответствии с man-страницей, -no-pie указывает gcc не создавать независимый от позиции исполняемый файл.

...