1 /* Support for relocating static PIE.
2 Copyright (C) 2017-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18 #define IS_IN_rtld // force inline function calls
25 #include <dl-startup.h>
28 extern ElfW(Addr
) _dl_load_base
;
31 reloc_static_pie (ElfW(Addr
) load_addr
);
34 reloc_static_pie(ElfW(Addr
) load_addr
)
39 struct elf_resolve tpnt_tmp
;
40 struct elf_resolve
*tpnt
= &tpnt_tmp
;
42 DL_BOOT_COMPUTE_GOT(got
);
43 DL_BOOT_COMPUTE_DYN(dpnt
, got
, (DL_LOADADDR_TYPE
)load_addr
);
45 _dl_memset(tpnt
, 0, sizeof(struct elf_resolve
));
46 tpnt
->loadaddr
= load_addr
;
47 tpnt
->dynamic_addr
= dpnt
;
49 __dl_parse_dynamic_info(dpnt
, tpnt
->dynamic_info
, NULL
, load_addr
);
51 #if defined(PERFORM_BOOTSTRAP_GOT)
52 /* some arches (like MIPS) we have to tweak the GOT before relocations */
53 PERFORM_BOOTSTRAP_GOT(tpnt
);
57 #if defined(ELF_MACHINE_PLTREL_OVERLAP)
63 for (indx
= 0; indx
< INDX_MAX
; indx
++) {
64 unsigned long rel_addr
, rel_size
;
65 ElfW(Word
) relative_count
= tpnt
->dynamic_info
[DT_RELCONT_IDX
];
67 rel_addr
= (indx
? tpnt
->dynamic_info
[DT_JMPREL
] :
68 tpnt
->dynamic_info
[DT_RELOC_TABLE_ADDR
]);
69 rel_size
= (indx
? tpnt
->dynamic_info
[DT_PLTRELSZ
] :
70 tpnt
->dynamic_info
[DT_RELOC_TABLE_SIZE
]);
75 if((0 == indx
) && relative_count
) {
76 rel_size
-= relative_count
* sizeof(ELF_RELOC
);
77 elf_machine_relative(load_addr
, rel_addr
, relative_count
);
78 rel_addr
+= relative_count
* sizeof(ELF_RELOC
);
81 #ifdef ARCH_NEEDS_BOOTSTRAP_RELOCS
86 unsigned long symbol_addr
;
88 unsigned long *reloc_addr
;
90 /* Now parse the relocation information */
91 rpnt
= (ELF_RELOC
*) rel_addr
;
92 for (i
= 0; i
< rel_size
; i
+= sizeof(ELF_RELOC
), rpnt
++) {
93 reloc_addr
= (unsigned long *) DL_RELOC_ADDR(load_addr
, (unsigned long)rpnt
->r_offset
);
94 symtab_index
= ELF_R_SYM(rpnt
->r_info
);
99 symtab
= (ElfW(Sym
) *) tpnt
->dynamic_info
[DT_SYMTAB
];
100 sym
= &symtab
[symtab_index
];
101 symbol_addr
= (unsigned long) DL_RELOC_ADDR(load_addr
, sym
->st_value
);
103 /* Use this machine-specific macro to perform the actual relocation. */
104 PERFORM_BOOTSTRAP_RELOC(rpnt
, reloc_addr
, symbol_addr
, load_addr
, sym
);
109 _dl_load_base
= load_addr
;