19a08862aSNagarathnam Muthusamy/* 29a08862aSNagarathnam Muthusamy * Linker script for vDSO. This is an ELF shared object prelinked to 39a08862aSNagarathnam Muthusamy * its virtual address, and with only one read-only segment. 49a08862aSNagarathnam Muthusamy * This script controls its layout. 59a08862aSNagarathnam Muthusamy */ 69a08862aSNagarathnam Muthusamy 79a08862aSNagarathnam Muthusamy#if defined(BUILD_VDSO64) 89a08862aSNagarathnam Muthusamy# define SHDR_SIZE 64 99a08862aSNagarathnam Muthusamy#elif defined(BUILD_VDSO32) 109a08862aSNagarathnam Muthusamy# define SHDR_SIZE 40 119a08862aSNagarathnam Muthusamy#else 129a08862aSNagarathnam Muthusamy# error unknown VDSO target 139a08862aSNagarathnam Muthusamy#endif 149a08862aSNagarathnam Muthusamy 159a08862aSNagarathnam Muthusamy#define NUM_FAKE_SHDRS 7 169a08862aSNagarathnam Muthusamy 179a08862aSNagarathnam MuthusamySECTIONS 189a08862aSNagarathnam Muthusamy{ 199a08862aSNagarathnam Muthusamy /* 209a08862aSNagarathnam Muthusamy * User/kernel shared data is before the vDSO. This may be a little 219a08862aSNagarathnam Muthusamy * uglier than putting it after the vDSO, but it avoids issues with 229a08862aSNagarathnam Muthusamy * non-allocatable things that dangle past the end of the PT_LOAD 239a08862aSNagarathnam Muthusamy * segment. Page size is 8192 for both 64-bit and 32-bit vdso binaries 249a08862aSNagarathnam Muthusamy */ 259a08862aSNagarathnam Muthusamy 269a08862aSNagarathnam Muthusamy vvar_start = . -8192; 279a08862aSNagarathnam Muthusamy vvar_data = vvar_start; 289a08862aSNagarathnam Muthusamy 299a08862aSNagarathnam Muthusamy . = SIZEOF_HEADERS; 309a08862aSNagarathnam Muthusamy 319a08862aSNagarathnam Muthusamy .hash : { *(.hash) } :text 329a08862aSNagarathnam Muthusamy .gnu.hash : { *(.gnu.hash) } 339a08862aSNagarathnam Muthusamy .dynsym : { *(.dynsym) } 349a08862aSNagarathnam Muthusamy .dynstr : { *(.dynstr) } 359a08862aSNagarathnam Muthusamy .gnu.version : { *(.gnu.version) } 369a08862aSNagarathnam Muthusamy .gnu.version_d : { *(.gnu.version_d) } 379a08862aSNagarathnam Muthusamy .gnu.version_r : { *(.gnu.version_r) } 389a08862aSNagarathnam Muthusamy 399a08862aSNagarathnam Muthusamy .dynamic : { *(.dynamic) } :text :dynamic 409a08862aSNagarathnam Muthusamy 419a08862aSNagarathnam Muthusamy .rodata : { 429a08862aSNagarathnam Muthusamy *(.rodata*) 439a08862aSNagarathnam Muthusamy *(.data*) 449a08862aSNagarathnam Muthusamy *(.sdata*) 459a08862aSNagarathnam Muthusamy *(.got.plt) *(.got) 469a08862aSNagarathnam Muthusamy *(.gnu.linkonce.d.*) 479a08862aSNagarathnam Muthusamy *(.bss*) 489a08862aSNagarathnam Muthusamy *(.dynbss*) 499a08862aSNagarathnam Muthusamy *(.gnu.linkonce.b.*) 509a08862aSNagarathnam Muthusamy 519a08862aSNagarathnam Muthusamy /* 529a08862aSNagarathnam Muthusamy * Ideally this would live in a C file: kept in here for 539a08862aSNagarathnam Muthusamy * compatibility with x86-64. 549a08862aSNagarathnam Muthusamy */ 559a08862aSNagarathnam Muthusamy VDSO_FAKE_SECTION_TABLE_START = .; 569a08862aSNagarathnam Muthusamy . = . + NUM_FAKE_SHDRS * SHDR_SIZE; 579a08862aSNagarathnam Muthusamy VDSO_FAKE_SECTION_TABLE_END = .; 589a08862aSNagarathnam Muthusamy } :text 599a08862aSNagarathnam Muthusamy 609a08862aSNagarathnam Muthusamy .fake_shstrtab : { *(.fake_shstrtab) } :text 619a08862aSNagarathnam Muthusamy 629a08862aSNagarathnam Muthusamy 639a08862aSNagarathnam Muthusamy .note : { *(.note.*) } :text :note 649a08862aSNagarathnam Muthusamy 659a08862aSNagarathnam Muthusamy .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr 669a08862aSNagarathnam Muthusamy .eh_frame : { KEEP (*(.eh_frame)) } :text 679a08862aSNagarathnam Muthusamy 689a08862aSNagarathnam Muthusamy 699a08862aSNagarathnam Muthusamy /* 709a08862aSNagarathnam Muthusamy * Text is well-separated from actual data: there's plenty of 719a08862aSNagarathnam Muthusamy * stuff that isn't used at runtime in between. 729a08862aSNagarathnam Muthusamy */ 739a08862aSNagarathnam Muthusamy 749a08862aSNagarathnam Muthusamy .text : { *(.text*) } :text =0x90909090, 759a08862aSNagarathnam Muthusamy 769a08862aSNagarathnam Muthusamy /DISCARD/ : { 779a08862aSNagarathnam Muthusamy *(.discard) 789a08862aSNagarathnam Muthusamy *(.discard.*) 799a08862aSNagarathnam Muthusamy *(__bug_table) 809a08862aSNagarathnam Muthusamy } 819a08862aSNagarathnam Muthusamy} 829a08862aSNagarathnam Muthusamy 839a08862aSNagarathnam Muthusamy/* 849a08862aSNagarathnam Muthusamy * Very old versions of ld do not recognize this name token; use the constant. 859a08862aSNagarathnam Muthusamy */ 869a08862aSNagarathnam Muthusamy#define PT_GNU_EH_FRAME 0x6474e550 879a08862aSNagarathnam Muthusamy 889a08862aSNagarathnam Muthusamy/* 899a08862aSNagarathnam Muthusamy * We must supply the ELF program headers explicitly to get just one 909a08862aSNagarathnam Muthusamy * PT_LOAD segment, and set the flags explicitly to make segments read-only. 919a08862aSNagarathnam Muthusamy */ 929a08862aSNagarathnam MuthusamyPHDRS 939a08862aSNagarathnam Muthusamy{ 949a08862aSNagarathnam Muthusamy text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ 959a08862aSNagarathnam Muthusamy dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ 969a08862aSNagarathnam Muthusamy note PT_NOTE FLAGS(4); /* PF_R */ 979a08862aSNagarathnam Muthusamy eh_frame_hdr PT_GNU_EH_FRAME; 989a08862aSNagarathnam Muthusamy} 99