2013-10-08 3 views
2

Итак, я знаю, что мы можем добавить пользовательский раздел в файл ELF и включить функции и структуры для отображения в пользовательские разделы. Это может быть сделано путем __atribute__ section("sectionname") Вот это readelf выход из моего текущего ELF, который имеет название пользовательских раздела .my_custom_section, который содержит структуру под названием ver_infoКак управлять разделом для сопоставления сегментов в файле ELF?

структура:

typedef struct version_info 
{ 
int  dd ; 
int  mm; 
int yy; 
int  hr; 
int  min; 
char  *software_type; 
char *software_version; 
char *hex_tools_version; 
}version_info; 

version_info ver_info __attribute__ ((section(".my_custom_section"))) = {7, 10, 2013, 17, 17, "some_type", "some_sw_version", "some_version"} ; 

Вот как эльф чтения выглядит следующим образом:

Section Headers: 
    [Nr] Name    Type   Addr  Off Size ES Flg Lk Inf Al 
    [ 0]     NULL   00000000 000000 000000 00  0 0 0 
    [ 1] .hash    HASH   000000d4 0000d4 00003c 04 A 2 0 4 
    [ 2] .dynsym   DYNSYM   00000110 000110 0000a0 10 A 3 5 4 
    [ 3] .dynstr   STRTAB   000001b0 0001b0 000026 00 A 0 0 1 
    [ 4] .rela.dyn   RELA   000001d8 0001d8 000024 0c A 2 0 4 
    [ 5] .plt    PROGBITS  00001000 001000 000000 00 AX 0 0 16 
    [ 6] .text    PROGBITS  00001000 001000 00001c 00 AX 0 0 4 
    [ 7] .rodata   PROGBITS  00002000 002000 000027 00 A 0 0 1 
    [ 8] .dynamic   DYNAMIC   00004000 003000 000078 08 WA 3 0 4 
    [ 9] .got    PROGBITS  00004078 003078 000000 00 WA 0 0 4 
    [10] .got.plt   PROGBITS  00004078 003078 000010 04 WA 0 0 8 
    [11] .my_custom_sectio PROGBITS  00004088 003088 000020 00 WA 0 0 4 
    [12] .bss    NOBITS   000040c0 0030a8 000000 00 WA 0 0 1 
    [13] .comment   PROGBITS  00000000 0030a8 000028 01 MS 0 0 1 
    [14] .shstrtab   STRTAB   00000000 0030d0 000081 00  0 0 1 
    [15] .symtab   SYMTAB   00000000 0033fc 000180 10  16 19 4 
    [16] .strtab   STRTAB   00000000 00357c 000075 00  0 0 1 

Program Headers: 
    Type   Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 
    LOAD   0x000000 0x00000000 0x00000000 0x001fc 0x001fc R 0x1000 
    LOAD   0x001000 0x00001000 0x00001000 0x0001c 0x0001c R E 0x1000 
    LOAD   0x002000 0x00002000 0x00002000 0x00027 0x00027 R 0x1000 
    LOAD   0x003000 0x00004000 0x00004000 0x000a8 0x000c0 RW 0x1000 
    DYNAMIC  0x003000 0x00004000 0x00004000 0x00078 0x00078 RW 0x4 

Section to Segment mapping: 
    Segment Sections... 
    00  .hash .dynsym .dynstr .rela.dyn 
    01  .text 
    02  .rodata 
    03  .dynamic .got.plt .my_custom_section 
    04  .dynamic 

в этом случае мой пользовательский раздел становится складчиной с .dynamic секций .got.plt и отображается в сегмент 03. Я хочу, чтобы отобразить этот раздел как отр само по себе. Можем ли мы иметь контроль над отображением раздела в сегмент? Как бы вы это сделали?

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

2.Use пользовательского компоновщика сценария: Я теперь с помощью пользовательского сценария компоновщика, который добавляет следующий раздел:

.my_custom_section() : 
    { 
    KEEP (*version_info.o (.rodata*)) 
    } 

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

ответ

2

Это инструкция, которую вы должны предоставить компоновщику. Именно то, как вы это делаете, зависит от того, какой компоновщик вы используете.

С GNU ld «правильным» способом является использование специального скрипта компоновщика, который вы можете предоставить с помощью опции -T. Вы можете увидеть сценарий компоновщика по умолчанию, набрав ld --verbose. Это аналогичная история для других линкеров: линкер BSD (как используется Mac OSX) использует файл заказа (указанный с -order_file), компоновщик Solaris использует файл карты (указанный с -M) и так далее. Все они делают почти то же самое.

Обратите внимание, что каждая платформа и каждое семейство ЦП обычно имеют свою собственную спецификацию ссылок, поэтому скрипт компоновщика GNU ld, который работает с объектами x86_64, может не работать на ARM, даже если они оба являются Linux. Это похоже на семейство BSD. Вообще говоря, вы должны получить скрипт компоновщика вашей платформы и внести поправку по мере необходимости. Вероятно, вы должны писать собственный скрипт компоновщика с нуля, если это требуется для настраиваемой платформы (например, это прошивка, вы пишете свою собственную ОС или что у вас есть).

Если это код, который должен быть кросс-платформенным, тогда нет хороших решений. Есть некоторые «неправильные» способы сделать это, которые могут работать, например, взлом с objcopy, но я не рекомендую их.

Сказав это, вы должны, вероятно, спросить себя, действительно ли это то, что вы хотите. Если вам нужны данные, некоторые пользовательские инструменты или фреймворк (например,динамический загрузчик ссылок) можно легко найти, не можете ли вы использовать dlsym или эквивалент?

+0

Ищите изменения в вопросе. Вместо этого я сделал редактирование, чтобы избежать длительного комментария. –

Смежные вопросы