У меня есть независимое рабочее место Linux x86_64 hello world:
main.S
.text
.global _start
_start:
asm_main_after_prologue:
/* Write */
mov $1, %rax /* syscall number */
mov $1, %rdi /* stdout */
lea msg(%rip), %rsi /* buffer */
mov $len, %rdx /* len */
syscall
/* Exit */
mov $60, %rax /* syscall number */
mov $0, %rdi /* exit status */
syscall
msg:
.ascii "hello\n"
len = . - msg
, который я могу собрать и запустить с:
as -o main.o main.S
ld -o main.out main.o
./main.out
Поскольку он не зависит от позиции из-за относительной нагрузки RIP , теперь я хотел связать его как PIE и посмотреть, как он загружается по случайным адресам каждый раз , чтобы повеселиться.
Сначала я попытался:
ld -pie -o main.out main.o
, но затем запустить его не удалось с помощью:
-bash: ./main.out: No such file or directory
и readelf -Wa
говорит, что вместо странного интерпретатора /lib/ld64.so.1
использовался вместообычный /lib64/ld-linux-x86-64.so.2
по какой-то причине.
Затем я узнал, что он на самом деле является рекомендуемым System V AMD64 ABI именем интерпретатора в 5.2.1 "Program Interpreter".
В любом случае, я тогда пытаюсь вызвать вопросы с помощью:
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o main.out main.o
, и теперь это работает: я получаю hello
, и исполняемый файл каждый раз загружается на другой адрес в соответствии с GDB.
Наконец, в качестве последнего шага я хотел также сделать этот исполняемый файл статически связным.чтобы сделать вещи еще более минимальными и, возможно, избавиться от явного -dynamic-linker
.
Вот чего я не мог сделать, и вот почему я спрашиваю здесь.
Если япопробуйте любой из:
ld -static -pie -o main.out main.o
ld -static -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o main.out main.o
-static
, кажется, не имеет никакого значения: я все еще получаю динамические исполняемые файлы .
После быстрого просмотра исходного кода ядра 5.0код в fs / binfmt_elf.c Я увидел этот интересный комментарий:
* There are effectively two types of ET_DYN
* binaries: programs (i.e. PIE: ET_DYN with INTERP)
* and loaders (ET_DYN without INTERP, since they
* _are_ the ELF interpreter). The loaders must
, поэтому я думаю, что когда я добьюсь того, чего хочу, у меня будет действительный переводчик, и я такЯ собираюсь использовать свой собственный минимальный hello world в качестве интерпретатора другой программы.
Одна вещь, которую я мог бы попробовать позже, это посмотреть, как какая-то реализация libc компилирует свой загрузчик и копирует его.
Связанный вопрос: Компилировать независимый от позиции исполняемый файл со статически связанной библиотекой на 64-битной машине , но в нем упоминается внешняя библиотека, поэтому, надеюсь, это более минималистично и ответственно.
Проверено в Ubuntu 18.10.