Смещение заголовка программы ELF - PullRequest
4 голосов
/ 24 февраля 2011

Я пишу исполняемый заголовок ELF + программный заголовок вручную следующим образом:

elf_head:
e_ident db      7Fh, 'ELF', 1, 1, 1
        times   9 db 0
e_type  dw      2                       ; ET_EXEC
e_mach  dw      3                       ; EM_386
e_ver   dd      1                       ; EV_CURRENT
e_entry dd      0x08048000+elf_head_len ; entry point
e_phoff dd      34h                     ; program header table offset
e_shoff dd      00h                     ; section header table offset
e_flags dd      0                       ; flags
e_elfhs dw      34h                     ; ELF header size
e_phes  dw      20h                     ; program header entry size
e_phec  dw      01h                     ; program header entries count
e_shes  dw      00h                     
e_shec  dw      00h                    
e_shsn  dw      00h                     
elf_ph:
p_type  dd      01h                     ; PT_LOAD
p_off   dd      elf_head_len        
p_vaddr dd      0x08048000+elf_head_len 
p_paddr dd      0x08048000+elf_head_len 
p_filsz dd      elf_head_len+file_len           
p_memsz dd      elf_head_len+file_len      
p_flags dd      7                       ; segment flags (RWX)
p_align dd      0x1000                  ; page_size==4096bytes
elf_head_len  equ  $ - elf_head

Я устанавливаю точку поля e_entry сразу после поля p_align, где я помещаю свой код в создаваемый файл.Но это не работает!Я немного запутался с полем p_offset.Я положил туда смещение от начала файла (0x00) до первого байта кода сегмента.Поскольку код сегмента начинается сразу после поля p_align, правильно ли я ввожу значение elf_head_len?Когда я пытаюсь запустить только что созданный исполняемый файл, bash отвечает: Ошибка сегментации!

Хорошо, я выясняю, что у меня возникла ошибка в программе, которая вызвала ошибку сегментации.(Извини за это).Но остается вопрос о поле p_off, и я также выясняю, что если я установлю p_off dd 0 и p_vaddr dd 0x08048000 и p_paddr dd 0x08048000, исполняемые файлы будут работать.Это также работает, если я ввожу p_off dd elf_head_len и p_vaddr dd 0x08048000 + elf_head_len и p_paddr dd 0x08048000 + elf_head_len.Это напоминает мне кое-что, что я читал в спецификации формата ELF о значениях p_off и p_vaddr, которые должны быть конгруэнтными (то есть я думаю, что они должны давать одинаковый результат, когда по модулю каждое из них имеет размер страницы).Вот почему программа работает с этими значениями.Таким образом, теперь возникает вопрос: если в приведенной выше логике есть ошибка, пожалуйста, исправьте ее.

1 Ответ

2 голосов
/ 24 февраля 2011

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

Эти ограничения те же, что и системный вызов mmap() для сопоставлений - он принимает сопоставления только со смещением в файле, кратном размеру страницы. При отображении файла ELF сегменты расширяются до ближайшей границы страницы, поэтому биты младшего разряда фактически игнорируются, за исключением вычисления размера сегмента.

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

...