Co GCC robi
Rozszerzanie kgiannakakis nieco więcej.
Te symbole są zdefiniowane przez PROVIDE
kluczowych skryptu linkera, udokumentowany w https://sourceware.org/binutils/docs-2.25/ld/PROVIDE.html#PROVIDE
domyślnej skrypty są generowane podczas budowania Binutils i osadzony w ld
wykonywalnego: pliki zewnętrzne, które mogą zostać zainstalowane w dystrybucji podobnie jak w /usr/lib/ldscripts
nie są używane domyślnie.
Echo skrypt linkera do wykorzystania:
ld -verbose | less
W binutils 2.24 zawiera:
.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) }
więc także odkryć, że:
__etext
i _etext
będzie również pracować
etext
nie jest końcem odcinka .text
, ale .fini
, który zawiera kod
etext
nie znajduje się na końcu tego segmentu z .rodata
po nim, ponieważ Binutils zrzuca wszystkie części tylko do odczytu w tym samym segmencie
PROVIDE
generuje słabe symbole: jeśli zdefiniujesz te symbole w swoim kodzie C, twoja definicja wygra i ukryje ten.
Minimal Linux 32-bit przykład
Aby naprawdę zrozumieć jak to wszystko działa, chciałbym stworzyć minimalne przykłady!
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)
}
}
skompilować i uruchomić:
gas --32 -o main.o main.S
ld -m elf_i386 -o main -T link.ld main.o
./main
echo $?
wyjściowa:
2
Objaśnienie: sdata
wskazuje na pierwszy bajt początku poniższej sekcji .data
.
Tak więc kontrolując pierwszy bajt tej sekcji, kontrolujemy stan wyjścia!
This example on GitHub.
Która strona podręcznika? –
Sprawdź 'man 3 end' –