mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 13:30:06 +00:00
* sysdeps/mips/dl-machine.h (_RTLD_PROLOGUE): Reformat. Declare
as function. (_RTLD_EPILOGUE): Reformat. Declare size of entry function. (ELF_MACHINE_BEFORE_RTLD_RELOC): Relocate the dynamic linker itself so it will even work when not loaded to the standard address. (RTLD_START): Reformat. Call _dl_start in a way that is safe even before the dynamic linker itself is relocated.
This commit is contained in:
parent
56eb5d1432
commit
921bb2c300
@ -37,13 +37,17 @@
|
|||||||
#define OFFSET_GP_GOT 0x7ff0
|
#define OFFSET_GP_GOT 0x7ff0
|
||||||
|
|
||||||
#ifndef _RTLD_PROLOGUE
|
#ifndef _RTLD_PROLOGUE
|
||||||
# define _RTLD_PROLOGUE(entry) "\n\t.globl " __STRING(entry) \
|
# define _RTLD_PROLOGUE(entry) \
|
||||||
"\n\t.ent " __STRING(entry) \
|
".globl\t" __STRING(entry) "\n\t" \
|
||||||
"\n\t" __STRING(entry) ":\n\t"
|
".ent\t" __STRING(entry) "\n\t" \
|
||||||
|
".type\t" __STRING(entry) ", @function\n" \
|
||||||
|
__STRING(entry) ":\n\t"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _RTLD_EPILOGUE
|
#ifndef _RTLD_EPILOGUE
|
||||||
# define _RTLD_EPILOGUE(entry) "\t.end " __STRING(entry) "\n"
|
# define _RTLD_EPILOGUE(entry) \
|
||||||
|
".end\t" __STRING(entry) "\n\t" \
|
||||||
|
".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.
|
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.
|
||||||
@ -134,6 +138,60 @@ elf_machine_load_address (void)
|
|||||||
/* The MSB of got[1] of a gnu object is set to identify gnu objects. */
|
/* The MSB of got[1] of a gnu object is set to identify gnu objects. */
|
||||||
#define ELF_MIPS_GNU_GOT1_MASK 0x80000000
|
#define ELF_MIPS_GNU_GOT1_MASK 0x80000000
|
||||||
|
|
||||||
|
/* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope
|
||||||
|
fiddles with global data. */
|
||||||
|
#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
|
||||||
|
do { \
|
||||||
|
struct link_map *map = &bootstrap_map; \
|
||||||
|
ElfW(Sym) *sym; \
|
||||||
|
ElfW(Addr) *got; \
|
||||||
|
int i, n; \
|
||||||
|
\
|
||||||
|
got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]); \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
if (__builtin_expect (map->l_addr == 0, 1)) \
|
||||||
|
goto done; \
|
||||||
|
\
|
||||||
|
/* got[0] is reserved. got[1] is also reserved for the dynamic object \
|
||||||
|
generated by gnu ld. Skip these reserved entries from \
|
||||||
|
relocation. */ \
|
||||||
|
i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1; \
|
||||||
|
n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val; \
|
||||||
|
\
|
||||||
|
/* Add the run-time display to all local got entries. */ \
|
||||||
|
while (i < n) \
|
||||||
|
got[i++] += map->l_addr; \
|
||||||
|
\
|
||||||
|
/* Handle global got entries. */ \
|
||||||
|
got += n; \
|
||||||
|
sym = (ElfW(Sym) *) D_PTR(map, l_info[DT_SYMTAB]) \
|
||||||
|
+ map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; \
|
||||||
|
i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val \
|
||||||
|
- map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val); \
|
||||||
|
\
|
||||||
|
while (i--) \
|
||||||
|
{ \
|
||||||
|
if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_COMMON) \
|
||||||
|
*got = map->l_addr + sym->st_value; \
|
||||||
|
else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC \
|
||||||
|
&& *got != sym->st_value) \
|
||||||
|
*got += map->l_addr; \
|
||||||
|
else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION) \
|
||||||
|
{ \
|
||||||
|
if (sym->st_other == 0) \
|
||||||
|
*got += map->l_addr; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
*got = map->l_addr + sym->st_value; \
|
||||||
|
\
|
||||||
|
got++; \
|
||||||
|
sym++; \
|
||||||
|
} \
|
||||||
|
done: \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* Get link map for callers object containing STUB_PC. */
|
/* Get link map for callers object containing STUB_PC. */
|
||||||
static inline struct link_map *
|
static inline struct link_map *
|
||||||
elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
|
elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
|
||||||
@ -354,10 +412,10 @@ _dl_runtime_resolve:\n \
|
|||||||
2) That under Linux the entry is named __start
|
2) That under Linux the entry is named __start
|
||||||
and not just plain _start. */
|
and not just plain _start. */
|
||||||
|
|
||||||
#define RTLD_START asm ("\
|
#define RTLD_START asm (\
|
||||||
.text\n"\
|
".text\n"\
|
||||||
_RTLD_PROLOGUE(ENTRY_POINT)\
|
_RTLD_PROLOGUE(ENTRY_POINT)\
|
||||||
" .globl _dl_start_user\n\
|
".set noreorder\n\
|
||||||
.set noreorder\n\
|
.set noreorder\n\
|
||||||
bltzal $0, 0f\n\
|
bltzal $0, 0f\n\
|
||||||
nop\n\
|
nop\n\
|
||||||
@ -371,10 +429,19 @@ _RTLD_PROLOGUE(ENTRY_POINT)\
|
|||||||
sw $4, -0x7ff0($28)\n\
|
sw $4, -0x7ff0($28)\n\
|
||||||
move $4, $29\n\
|
move $4, $29\n\
|
||||||
subu $29, 16\n\
|
subu $29, 16\n\
|
||||||
jal _dl_start\n\
|
\n\
|
||||||
|
la $8, coff\n\
|
||||||
|
bltzal $8, coff\n\
|
||||||
|
coff: subu $8, $31, $8\n\
|
||||||
|
\n\
|
||||||
|
la $25, _dl_start\n\
|
||||||
|
addu $25, $8\n\
|
||||||
|
jalr $25\n\
|
||||||
|
\n\
|
||||||
addiu $29, 16\n\
|
addiu $29, 16\n\
|
||||||
# Get the value of label '_dl_start_user' in t9 ($25).\n\
|
# Get the value of label '_dl_start_user' in t9 ($25).\n\
|
||||||
la $25, _dl_start_user\n\
|
la $25, _dl_start_user\n\
|
||||||
|
.globl _dl_start_user\n\
|
||||||
_dl_start_user:\n\
|
_dl_start_user:\n\
|
||||||
.set noreorder\n\
|
.set noreorder\n\
|
||||||
.cpload $25\n\
|
.cpload $25\n\
|
||||||
@ -410,9 +477,9 @@ _dl_start_user:\n\
|
|||||||
la $2, _dl_fini\n\
|
la $2, _dl_fini\n\
|
||||||
# Jump to the user entry point.\n\
|
# Jump to the user entry point.\n\
|
||||||
move $25, $17\n\
|
move $25, $17\n\
|
||||||
jr $25\n"\
|
jr $25\n\t"\
|
||||||
_RTLD_EPILOGUE(ENTRY_POINT)\
|
_RTLD_EPILOGUE(ENTRY_POINT)\
|
||||||
"\n.previous"\
|
".previous"\
|
||||||
);
|
);
|
||||||
|
|
||||||
/* The MIPS never uses Elfxx_Rela relocations. */
|
/* The MIPS never uses Elfxx_Rela relocations. */
|
||||||
@ -513,7 +580,7 @@ elf_machine_got_rel (struct link_map *map, int lazy)
|
|||||||
|
|
||||||
/* got[0] is reserved. got[1] is also reserved for the dynamic object
|
/* got[0] is reserved. got[1] is also reserved for the dynamic object
|
||||||
generated by gnu ld. Skip these reserved entries from relocation. */
|
generated by gnu ld. Skip these reserved entries from relocation. */
|
||||||
i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2: 1;
|
i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;
|
||||||
n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
|
n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
|
||||||
/* Add the run-time display to all local got entries if needed. */
|
/* Add the run-time display to all local got entries if needed. */
|
||||||
if (__builtin_expect (map->l_addr != 0, 0))
|
if (__builtin_expect (map->l_addr != 0, 0))
|
||||||
|
Loading…
Reference in New Issue
Block a user