Что делает GCC
Расширение kgiannakakis немного больше.
Эти символы определяются PROVIDE
ключевого слова сценария линкера, документированы https://sourceware.org/binutils/docs-2.25/ld/PROVIDE.html#PROVIDE
скрипты генерируются при создании Binutils по умолчанию и встраивается в ld
исполняемому: внешние файлы, которые могут быть установлены в вашем дистрибутиве например, в /usr/lib/ldscripts
, по умолчанию не используются.
Echo компоновщик скрипт для использования:
ld -verbose | less
В Binutils 2.24 содержит:
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
Таким образом, мы также обнаружили, что:
__etext
и _etext
также будет работать
etext
не конец секции .text
, а .fini
, который также содержит код
etext
не в конце сегмента, с .rodata
после него, так как Binutils сбрасывает все только для чтения разделов в том же сегменте
PROVIDE
генерирует слабые символы: если вы также определяете эти символы в своем коде C, ваше определение победит и скроет это.
Minimal Linux 32-битный пример
Чтобы по-настоящему понять, как работают вещи, я хотел бы создать минимальные примеры!
main.S
:
.section .text
/* Exit system call. */
mov $1, %eax
/* Exit status. */
mov sdata, %ebx
int $0x80
.section .data
.byte 2
link.ld
:
SECTIONS
{
. = 0x400000;
.text :
{
*(.text)
sdata = .;
*(.data)
}
}
компилировать и запускать:
gas --32 -o main.o main.S
ld -m elf_i386 -o main -T link.ld main.o
./main
echo $?
Выход:
2
Пояснение: sdata
указывает на первый байт начала раздела .data
.
Итак, контролируя первый байт этого раздела, мы контролируем статус выхода!
This example on GitHub.
Какую страницу руководства? –
Проверьте 'man 3 end' – 2009-11-20 00:00:43