diff options
author | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2004-08-17 13:37:54 +0000 |
---|---|---|
committer | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2004-08-17 13:37:54 +0000 |
commit | 6d6f3a5c26adcf6b105edfb4b53e97ceee81944c (patch) | |
tree | fdf250e80080d49b1e421f7157661033821c5fb7 /ldso/ldso/dl-elf.c | |
parent | d965f80088fafaacfd33d0b0770724f4fbcbe6e5 (diff) |
Let ldso decide if it should relocate itselft a second time. This
is needed if ldso should use libcs malloc whenever possible.
Fix RTLD_LAZY propagation to RTLD_NOW relocation when requested by
libdl.
Diffstat (limited to 'ldso/ldso/dl-elf.c')
-rw-r--r-- | ldso/ldso/dl-elf.c | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 25c82401f..8af9e78f6 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -730,15 +730,15 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, return tpnt; } - -int _dl_fixup(struct dyn_elf *rpnt, int flag) +/* now_flag must be RTLD_NOW or zero */ +int _dl_fixup(struct dyn_elf *rpnt, int now_flag) { int goof = 0; struct elf_resolve *tpnt; unsigned long reloc_size; if (rpnt->next) - goof += _dl_fixup(rpnt->next, flag); + goof += _dl_fixup(rpnt->next, now_flag); tpnt = rpnt->dyn; #if defined (__SUPPORT_LD_DEBUG__) @@ -756,28 +756,25 @@ int _dl_fixup(struct dyn_elf *rpnt, int flag) return goof; } + reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE]; /* On some machines, notably SPARC & PPC, DT_REL* includes DT_JMPREL in its range. Note that according to the ELF spec, this is completely legal! */ #ifdef ELF_MACHINE_PLTREL_OVERLAP - reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE] - - tpnt->dynamic_info [DT_PLTRELSZ]; -#else - reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE]; + reloc_size -= tpnt->dynamic_info [DT_PLTRELSZ]; #endif - if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]) { - if (tpnt->init_flag & RELOCS_DONE) - return goof; + if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] && + !(tpnt->init_flag & RELOCS_DONE)) { tpnt->init_flag |= RELOCS_DONE; goof += _dl_parse_relocation_information(rpnt, tpnt->dynamic_info[DT_RELOC_TABLE_ADDR], reloc_size, 0); } - - if (tpnt->dynamic_info[DT_JMPREL]) { - if (tpnt->init_flag & JMP_RELOCS_DONE) - return goof; + if (tpnt->dynamic_info[DT_JMPREL] && + (!(tpnt->init_flag & JMP_RELOCS_DONE) || + (now_flag && !(tpnt->rtld_flags & now_flag)))) { + tpnt->rtld_flags |= now_flag; tpnt->init_flag |= JMP_RELOCS_DONE; - if (flag & RTLD_LAZY) { + if (!(tpnt->rtld_flags & RTLD_NOW)) { _dl_parse_lazy_relocation_information(rpnt, tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info [DT_PLTRELSZ], 0); |