Ld скрипт: поведение . в сегментах?Linux

Ответить Пред. темаСлед. тема
Anonymous
 Ld скрипт: поведение . в сегментах?

Сообщение Anonymous »

У меня есть программа на C, которую я пытаюсь связать с помощью ld таким образом, чтобы получить следующий макет заголовка программы ELF64:

Код: Выделить всё

PHDRS
{
phdr PT_PHDR FLAGS(4) FILEHDR PHDRS;
interp PT_INTERP FLAGS(4);
text PT_LOAD FLAGS(5) FILEHDR PHDRS;
dynamic PT_DYNAMIC FLAGS(6);
data PT_LOAD FLAGS(6);
rodata PT_LOAD FLAGS(4);
note PT_NOTE FLAGS(4);
tls PT_TLS FLAGS(6);
eh_frame PT_GNU_EH_FRAME;
relro PT_GNU_RELRO;
}
Я впервые писал сценарий компоновщика, поэтому я скопировал сценарий по умолчанию из ld --verbose и поместил каждый входной раздел в соответствующий сегмент. В итоге у меня получилось что-то вроде этого (большинство строк опущено для краткости, но они были идентичны):

Код: Выделить всё

SECTIONS
{
. = SIZEOF_HEADERS;

.interp : { *(.interp) } :interpreter :rodata

.note.gnu.build-id : { *(.note.gnu.build-id) } :note :rodata

.hash : { *(.hash) } :rodata
.gnu.hash : { *(.gnu.hash) } :rodata

.dynsym : { *(.dynsym) } :rodata
.dynstr : { *(.dynstr) } :rodata

.relr.dyn : { *(.relr.dyn) } :rodata

.init : { KEEP (*(SORT_NONE(.init))) } :text

.plt : { *(.plt) *(.iplt) } :text
.plt.got : { *(.plt.got) } :data
.plt.sec : { *(.plt.sec) } :data

.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } :rodata :eh_frame
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } :rodata

.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
} :data :tls
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } :data :tls

.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } :data :relro

.dynamic : { *(.dynamic) } :dynamic :data :relro

.got : { *(.got) *(.igot) } :data :relro
.got.plt : { *(.got.plt) *(.igot.plt) } :data :relro
.data : {
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
} :data
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(. != 0 ? 64 / 8 : 1);
} :data
}

К сожалению, когда я попытался протестировать приведенный выше сценарий на тривиальном файле C, вызвав gcc a.c -fPIC -Wl,-T,script.ld, возникла проблема . Когда я посмотрел на вывод readelf -l, я увидел:

Код: Выделить всё

Type           Offset             VirtAddr           PhysAddr
FileSiz            MemSiz              Flags  Align
...
LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000000006b1 0x00000000000006b1 R E   0x1000
...
LOAD           0x00000000000017a0 0x00000000000007a0 0x00000000000007a0
0x0000000000000248 0x0000000000000250 RW    0x1000
LOAD           0x0000000000001270 0x0000000000000270 0x0000000000000270
0x000000000000052d 0x000000000000052d R     0x1000
...
, поэтому все три сегмента загрузки борются за одну и ту же страницу в памяти.
Я попробовал добавить . = ALIGN(0x1000); в строке перед первым использованием каждого имени phdr, чтобы посмотреть, не переместит ли это сегменты на отдельные страницы в виртуальной памяти, но это не сработало — разделы все равно перекрывались.
Корень проблемы в том, что я не понимаю, как ld "." Счетчик местоположения ведет себя по отношению к сегментам. Когда PHDRS не указан, из примеров в документации ld видно, что это монотонный указатель, который увеличивается на размер раздела каждый раз, когда создается новый выходной раздел. А вот если заголовки программы s1 и s2 именно в таком порядке и я пишу

Код: Выделить всё

.a: { *(.a) } :s1
.b: { *(.b) } :s2
.c: { *(.c) } :s1
Я не уверен, к чему это приведет "." будь то в конце первого сезона, или в конце второго сезона, или где-то еще.
Если бы кто-нибудь мог указать мне на некоторые ресурсы по этому вопросу, чтобы я мог лучше понять, я был бы очень признателен.

Подробнее здесь: https://stackoverflow.com/questions/791 ... n-segments
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Ld скрипт: поведение . в сегментах?
    Anonymous » » в форуме Linux
    0 Ответы
    37 Просмотры
    Последнее сообщение Anonymous
  • Как ключи хранятся в сегментах в C++
    Гость » » в форуме C++
    0 Ответы
    28 Просмотры
    Последнее сообщение Гость
  • Как ключи хранятся в сегментах в C++
    Гость » » в форуме C++
    0 Ответы
    24 Просмотры
    Последнее сообщение Гость
  • Невозможно найти компонент в сегментах имени
    Anonymous » » в форуме JAVA
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Поиск определенного значения в определенном поле, во многих файлах CSV, во многих сегментах, в трех проектах в GCS с исп
    Anonymous » » в форуме Python
    0 Ответы
    51 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Linux»