102 lines
3.3 KiB
Plaintext
102 lines
3.3 KiB
Plaintext
/*
|
|
* Linker script for the VDSO.
|
|
*
|
|
* The VDSO is essentially a normal ELF shared library that is mapped into the
|
|
* address space of the process that is going to use it. The address of the
|
|
* VDSO is passed to the runtime linker in the AT_SYSINFO_EHDR entry of the aux
|
|
* vector.
|
|
*
|
|
* There are, however, three ways in which the VDSO differs from a normal
|
|
* shared library:
|
|
*
|
|
* - The runtime linker does not attempt to process any relocations for the
|
|
* VDSO so it is the responsibility of whoever loads the VDSO into the
|
|
* address space to do this if necessary. Because of this restriction we are
|
|
* careful to ensure that the VDSO does not need to have any relocations
|
|
* applied to it.
|
|
*
|
|
* - Although the VDSO is position independent and would normally be linked at
|
|
* virtual address 0, the Linux kernel VDSO is actually linked at a non zero
|
|
* virtual address and the code in the system runtime linker that handles the
|
|
* VDSO expects this to be the case so we have to explicitly link this VDSO
|
|
* at a non zero address. The actual address is arbitrary, but we use the
|
|
* same one as the Linux kernel VDSO.
|
|
*
|
|
* - The VDSO will be directly mmapped by the sentry, rather than going through
|
|
* a normal ELF loading process. The VDSO must be carefully constructed such
|
|
* that the layout in the ELF file is identical to the layout in memory.
|
|
*/
|
|
|
|
VDSO_PRELINK = 0xffffffffff700000;
|
|
|
|
SECTIONS {
|
|
/* The parameter page is mapped just before the VDSO. */
|
|
_params = VDSO_PRELINK - 0x1000;
|
|
|
|
. = VDSO_PRELINK + SIZEOF_HEADERS;
|
|
|
|
.hash : { *(.hash) } :text
|
|
.gnu.hash : { *(.gnu.hash) }
|
|
.dynsym : { *(.dynsym) }
|
|
.dynstr : { *(.dynstr) }
|
|
.gnu.version : { *(.gnu.version) }
|
|
.gnu.version_d : { *(.gnu.version_d) }
|
|
.gnu.version_r : { *(.gnu.version_r) }
|
|
|
|
.note : { *(.note.*) } :text :note
|
|
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
|
|
.eh_frame : { KEEP (*(.eh_frame)) } :text
|
|
|
|
.dynamic : { *(.dynamic) } :text :dynamic
|
|
|
|
.rodata : { *(.rodata*) } :text
|
|
|
|
.altinstructions : { *(.altinstructions) }
|
|
.altinstr_replacement : { *(.altinstr_replacement) }
|
|
|
|
/*
|
|
* TODO(gvisor.dev/issue/157): Remove this alignment? Then the VDSO would fit
|
|
* in a single page.
|
|
*/
|
|
. = ALIGN(0x1000);
|
|
.text : { *(.text*) } :text =0x90909090
|
|
|
|
/*
|
|
* N.B. There is no data/bss section. This VDSO neither needs nor uses a data
|
|
* section. We omit it entirely because some gcc/clang and gold/bfd version
|
|
* combinations struggle to handle an empty data PHDR segment (internal
|
|
* linker assertion failures result).
|
|
*
|
|
* If the VDSO does incorrectly include a data section, the linker will
|
|
* include it in the text segment. check_vdso.py looks for this degenerate
|
|
* case.
|
|
*/
|
|
}
|
|
|
|
PHDRS {
|
|
text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R | PF_X */
|
|
dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
|
|
note PT_NOTE FLAGS(4); /* PF_R */
|
|
eh_frame_hdr PT_GNU_EH_FRAME;
|
|
}
|
|
|
|
/*
|
|
* Define the symbols that are to be exported.
|
|
*/
|
|
VERSION {
|
|
LINUX_2.6 {
|
|
global:
|
|
clock_gettime;
|
|
__vdso_clock_gettime;
|
|
gettimeofday;
|
|
__vdso_gettimeofday;
|
|
getcpu;
|
|
__vdso_getcpu;
|
|
time;
|
|
__vdso_time;
|
|
|
|
local: *;
|
|
};
|
|
}
|