summaryrefslogtreecommitdiff
path: root/ldso/ldso/dl-elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/dl-elf.c')
-rw-r--r--ldso/ldso/dl-elf.c27
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);