Несмотря на то, что инструмент и концепция prelink(8)
широко презираются (и, вероятно, не поставляются в вашем дистрибутиве), вы можете использовать его для связывания библиотек в двоичном коде с нехваткой памяти:
-r --reloc-only=ADDRESS
Instead of prelinking, just relink given shared libraries
to the specified base address.
Поскольку адрес, по которому библиотеки будут отображаться в процессе, определяется ld(1)
, вы можете изменить Makefile
для вызова ld
с другими значениями --section-start
:
--section-start SECTION=ADDRESS
Set address of named section
-Tbss ADDRESS Set address of .bss section
-Tdata ADDRESS Set address of .data section
-Ttext ADDRESS Set address of .text section
-Ttext-segment ADDRESS Set address of text segment
Я переместил сегменты текста и bss вниз по младшим адресам:
$ gcc -Wl,-Ttext-segment=0x200000 -Wl,-Tbss=0x400000 -o broken broken.c
$ readelf -a broken
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x200450
...
Если вы можете переместить все разделы, предоставленные в исполняемом файле, с помощью --section-start
и переместить библиотеки вниз с помощью prelink(8)
, вы сможете загрузить весь код размером менее 4 гигабайт.