/* * 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: 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: *; }; }