Hi it is me again.
This is the latest ldso patch. the NEW weak symbol handling works now
with a little special handling in _dl_find_hash(). You get to chose
if you want the new or old handling :)
There was 2 missing _dl_check_if_named_library_is_loaded() calls in _dlopen().
I then disabled the _dl_check_if_named_library_is_loaded() in dl-elf.c since
it is rendundant.
Question, why does some _dl_linux_resolver(), like i386, have 2 calls
to _dl_find_hash()? I think that is wrong, isn't it?
I really hope you can check this out soon ...
# define UNSUPPORTED_RELOC_STR "RELA"
#endif
+/* Reloc type classes as returned by elf_machine_type_class().
+ ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by
+ some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be
+ satisfied by any symbol in the executable. Some architectures do
+ not support copy relocations. In this case we define the macro to
+ zero so that the code for handling them gets automatically optimized
+ out. */
+#define ELF_RTYPE_CLASS_PLT 1
+#ifndef DL_NO_COPY_RELOCS
+# define ELF_RTYPE_CLASS_COPY 2
+#else
+# define ELF_RTYPE_CLASS_COPY 0
+#endif
/* Convert between the Linux flags for page protections and the
char * loadaddr, unsigned long * dynamic_info,
unsigned long dynamic_addr, unsigned long dynamic_size);
-enum caller_type{symbolrel=0,copyrel=1,resolver=2};
extern char * _dl_find_hash(const char * name, struct dyn_elf * rpnt1,
- struct elf_resolve * f_tpnt, enum caller_type);
+ int type_class);
extern int _dl_linux_dynamic_link(void);
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_ARM_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY))
int reloc_type;
ELF_RELOC *this_reloc;
char *strtab;
+ char *symname;
Elf32_Sym *symtab;
ELF_RELOC *rel_addr;
int symtab_index;
symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+ symname = strtab + symtab[symtab_index].st_name;
if (reloc_type != R_ARM_JUMP_SLOT) {
got_addr = (char **) instr_addr;
/* Get the address of the GOT entry */
- new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope, tpnt, resolver);
+ new_addr = _dl_find_hash(symname,
+ tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
if (!new_addr) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
- _dl_progname, strtab + symtab[symtab_index].st_name);
+ _dl_progname, symname);
_dl_exit(1);
};
#if defined (__SUPPORT_LD_DEBUG__)
{
if (_dl_debug_bindings)
{
- _dl_dprintf(_dl_debug_file, "\nresolve function: %s",
- strtab + symtab[symtab_index].st_name);
+ _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
if(_dl_debug_detail) _dl_dprintf(_dl_debug_file,
"\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr);
}
if (symtab_index) {
symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name,
- scope, (reloc_type == R_ARM_JUMP_SLOT ? tpnt : NULL), symbolrel);
+ scope, elf_machine_type_class(reloc_type));
/*
* We want to allow undefined references to weak symbols - this might
symbol_addr = (unsigned long) _dl_find_hash(strtab +
symtab[symtab_index].st_name, scope,
- NULL, copyrel);
+ ELF_RTYPE_CLASS_COPY);
if (!symbol_addr) goof++;
}
if (!goof) {
#define PAGE_ALIGN 0xffffe000
#define ADDR_ALIGN 0x1fff
#define OFFS_ALIGN 0xffffe000
+
+/* The union of reloc-type-classes where the reloc TYPE is a member.
+
+ TYPE is in the class ELF_RTYPE_CLASS_PLT if it can describe a
+ relocation for a PLT entry, that is, for which a PLT entry should not
+ be allowed to define the value. The GNU linker for CRIS can merge a
+ .got.plt entry (R_CRIS_JUMP_SLOT) with a .got entry (R_CRIS_GLOB_DAT),
+ so we need to match both these reloc types.
+
+ TYPE is in the class ELF_RTYPE_CLASS_NOCOPY if it should not be allowed
+ to resolve to one of the main executable's symbols, as for a COPY
+ reloc. */
+#define elf_machine_type_class(type) \
+ ((((((type) == R_CRIS_JUMP_SLOT)) \
+ || ((type) == R_CRIS_GLOB_DAT)) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_CRIS_COPY) * ELF_RTYPE_CLASS_COPY))
got_addr = (char **) instr_addr;
/* Fetch the address of the GOT entry. */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
-
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
if (!new_addr) {
- new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
-
- if (new_addr)
- return (unsigned long) new_addr;
-
- _dl_dprintf(2, "%s: Can't resolv symbol '%s'\n", _dl_progname, symname);
- _dl_exit(1);
+ _dl_dprintf(2, "%s: Can't resolv symbol '%s'\n", _dl_progname, symname);
+ _dl_exit(1);
}
#if defined (__SUPPORT_LD_DEBUG__)
}
else {
symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
- (reloc_type == R_CRIS_JUMP_SLOT ? tpnt : NULL), symbolrel);
+ elf_machine_type_class(reloc_type));
}
if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
goof = 0;
if (symtab_index) {
- symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
+ symbol_addr = (unsigned long) _dl_find_hash(symname, scope, ELF_RTYPE_CLASS_COPY);
if (!symbol_addr)
goof++;
if (pnt1) {
libname = pnt1 + 1;
}
-
+#if 0
/* Critical step! Weed out duplicates early to avoid
* function aliasing, which wastes memory, and causes
* really bad things to happen with weaks and globals. */
if ((tpnt1=_dl_check_if_named_library_is_loaded(libname, trace_loaded_objects))!=NULL)
return tpnt1;
+#endif
#if defined (__SUPPORT_LD_DEBUG__)
if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfind library='%s'; searching\n", libname);
* relocations or when we call an entry in the PLT table for the first time.
*/
char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
- struct elf_resolve *f_tpnt, enum caller_type caller_type)
+ int type_class)
{
struct elf_resolve *tpnt;
int si;
Elf32_Sym *symtab;
unsigned long elf_hash_number, hn;
char *weak_result;
- struct dyn_elf *rpnt, first;
+ struct dyn_elf *rpnt;
const ElfW(Sym) *sym;
weak_result = 0;
elf_hash_number = _dl_elf_hash(name);
- /* A quick little hack to make sure that any symbol in the executable
- will be preferred to one in a shared library. This is necessary so
- that any shared library data symbols referenced in the executable
- will be seen at the same address by the executable, shared libraries
- and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
- if (_dl_symbol_tables && rpnt1) {
- first = (*_dl_symbol_tables);
- first.next = rpnt1;
- rpnt1 = (&first);
- }
-
/*
* The passes are so that we can first search the regular symbols
* for whatever module was specified, and then search anything
* starting the first dlopened module, and anything above that
* is just the next one in the chain.
*/
+ if (rpnt1 == NULL)
+ rpnt1 = _dl_symbol_tables;
+
for (pass = 0; (1 == 1); pass++) {
/*
* If we are just starting to search for RTLD_GLOBAL, setup
* the pointer for the start of the search.
*/
- if (pass == 1) {
+ if (pass == 1)
rpnt1 = _dl_handles;
- }
/*
* Anything after this, we need to skip to the next module.
*/
- else if (pass >= 2) {
+ else if (pass >= 2)
rpnt1 = rpnt1->next_handle;
- }
/*
- * Make sure we still have a module, and make sure that this
- * module was loaded with RTLD_GLOBAL.
+ * Make sure we still have a module.
*/
- if (pass != 0) {
if (rpnt1 == NULL)
break;
- //if ((rpnt1->flags & RTLD_GLOBAL) == 0)
- //continue;
- }
- for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
+ for (rpnt = rpnt1; rpnt; rpnt = rpnt->next) {
tpnt = rpnt->dyn;
/* Don't search the executable when resolving a copy reloc. */
- if (tpnt->libtype == elf_executable && caller_type == copyrel)
+ if ((type_class & ELF_RTYPE_CLASS_COPY) && tpnt->libtype == elf_executable)
continue;
/*
continue;
if (ELF32_ST_TYPE(sym->st_info) > STT_FUNC)
continue;
- if (sym->st_shndx == SHN_UNDEF && caller_type != copyrel)
+ if (type_class & (sym->st_shndx == SHN_UNDEF))
continue;
if (_dl_strcmp(strtab + sym->st_name, name) != 0)
continue;
switch (ELF32_ST_BIND(sym->st_info)) {
case STB_WEAK:
-//Disable this to match current glibc behavior. Of course,
-//this doesn't actually work yet and will cause segfaults...
-#if 1
+#ifndef __LIBDL_SHARED__
+/*
+Due to a special hack in libdl.c, one must handle the _dl_ symbols
+according to the OLD weak symbol scheme. This stuff can be deleted
+once that hack has been fixed.
+*/
+
+ if(_dl_symbol((char *)name)) {
if (!weak_result)
weak_result = (char *)tpnt->loadaddr + sym->st_value;
break;
+ }
#endif
case STB_GLOBAL:
return (char*)tpnt->loadaddr + sym->st_value;
/* We only do a partial dynamic linking right now. The user
is not supposed to define any symbols that start with a
'_dl', so we can do this with confidence. */
- if (!symname || symname[0] != '_' ||
- symname[1] != 'd' || symname[2] != 'l' || symname[3] != '_')
- {
+ if (!symname || !_dl_symbol(symname)) {
continue;
}
+
symbol_addr = load_addr + symtab[symtab_index].st_value;
if (!symbol_addr) {
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_386_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY))
strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
symname= strtab + symtab[symtab_index].st_name;
- if (reloc_type != R_386_JMP_SLOT) {
+ if (unlikely(reloc_type != R_386_JMP_SLOT)) {
_dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n",
_dl_progname);
_dl_exit(1);
got_addr = (char **) instr_addr;
/* Get the address of the GOT entry */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
- if (!new_addr) {
- new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
- if (new_addr) {
- return (unsigned long) new_addr;
- }
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ if (unlikely(!new_addr)) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
_dl_exit(1);
- }
+ };
#if defined (__SUPPORT_LD_DEBUG__)
if ((unsigned long) got_addr < 0x40000000)
if (symtab_index) {
symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
- (reloc_type == R_386_JMP_SLOT ? tpnt : NULL), symbolrel);
+ elf_machine_type_class(reloc_type));
/*
* We want to allow undefined references to weak symbols - this might
symname = strtab + symtab[symtab_index].st_name;
if (symtab_index) {
- symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
+ symbol_addr = (unsigned long) _dl_find_hash(symname, scope, ELF_RTYPE_CLASS_COPY);
if (!symbol_addr) goof++;
}
if (!goof) {
up each symbol individually. */
- _dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("___brk_addr", NULL, NULL, symbolrel);
+ _dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("___brk_addr", NULL, 0);
if (_dl_brkp) {
*_dl_brkp = brk_addr;
}
- _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, NULL, symbolrel);
+ _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, 0);
if (_dl_envp) {
*_dl_envp = (unsigned long) envp;
}
#endif
- _dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", NULL, NULL, symbolrel);
+ _dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", NULL, 0);
#if defined (__SUPPORT_LD_DEBUG__)
_dl_on_exit = (int (*)(void (*)(int, void *),void*))
- (intptr_t) _dl_find_hash("on_exit", NULL, NULL, symbolrel);
+ (intptr_t) _dl_find_hash("on_exit", NULL, 0);
#endif
/* Notify the debugger we have added some objects. */
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_68K_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_68K_COPY) * ELF_RTYPE_CLASS_COPY))
/* Get the address of the GOT entry. */
new_addr = _dl_find_hash (strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope, tpnt, resolver);
+ tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
if (!new_addr)
{
_dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
symbol_addr = (unsigned int)
_dl_find_hash (strtab + symtab[symtab_index].st_name,
tpnt->symbol_scope,
- reloc_type == R_68K_JMP_SLOT ? tpnt : NULL, symbolrel);
+ elf_machine_type_class(reloc_type));
/* We want to allow undefined references to weak symbols -
this might have been intentional. We should not be
{
symbol_addr = (unsigned int)
_dl_find_hash (strtab + symtab[symtab_index].st_name,
- xpnt->next, NULL, copyrel);
+ xpnt->next, ELF_RTYPE_CLASS_COPY);
if (!symbol_addr)
{
_dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+
+#define elf_machine_type_class(type) ELF_RTYPE_CLASS_PLT
strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
symname = strtab + sym->st_name;
- new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
- tpnt->symbol_scope, tpnt, resolver);
+ new_addr = (unsigned long) _dl_find_hash(symname,
+ tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+ if (!new_addr) {
+ _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
+ _dl_progname, symname);
+ _dl_exit (1);
+ }
/* Address of jump instruction to fix up */
instr_addr = (unsigned long) (got + local_gotno + sym_index - gotsym);
*got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
else {
*got_entry = (unsigned long) _dl_find_hash(strtab +
- sym->st_name, tpnt->symbol_scope, NULL, copyrel);
+ sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_COPY);
}
}
else if (sym->st_shndx == SHN_COMMON) {
*got_entry = (unsigned long) _dl_find_hash(strtab +
- sym->st_name, tpnt->symbol_scope, NULL, copyrel);
+ sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_COPY);
}
else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
*got_entry != sym->st_value)
}
else {
*got_entry = (unsigned long) _dl_find_hash(strtab +
- sym->st_name, tpnt->symbol_scope, NULL, copyrel);
+ sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_COPY);
}
got_entry++;
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+/* We never want to use a PLT entry as the destination of a
+ reloc, when what is being relocated is a branch. This is
+ partly for efficiency, but mostly so we avoid loops. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_PPC_JMP_SLOT \
+ || (type) == R_PPC_REL24 \
+ || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY))
#endif
/* Get the address of the GOT entry */
- finaladdr = (Elf32_Addr) _dl_find_hash(strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope, tpnt, resolver);
+ finaladdr = (Elf32_Addr) _dl_find_hash(symname,
+ tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
if (!finaladdr) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
_dl_exit(1);
delta = finaladdr - (Elf32_Word)reloc_addr;
if (delta<<6>>6 == delta) {
*reloc_addr = OPCODE_B(delta);
-#if 0
- /* this will almost never be true */
- } else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000) {
+ } else if (finaladdr <= 0x01fffffc) {
*reloc_addr = OPCODE_BA (finaladdr);
-#endif
} else {
/* Warning: we don't handle double-sized PLT entries */
Elf32_Word *plt, *data_words, index, offset;
char *symname;
Elf32_Addr *reloc_addr;
Elf32_Addr finaladdr;
- struct dyn_elf *sym_scope;
unsigned long symbol_addr;
#if defined (__SUPPORT_LD_DEBUG__)
symtab_index = ELF32_R_SYM(rpnt->r_info);
symname = strtab + symtab[symtab_index].st_name;
-#if 1
- sym_scope = scope->dyn->symbol_scope;
-#else
- /* Funny, this works too and appears to be much faster. */
- sym_scope = scope;
-#endif
- if (reloc_type == R_PPC_COPY) {
- sym_scope = scope->next;
- tpnt = NULL; /* To be or not to be ...*/
- }
- symbol_addr = (unsigned long) _dl_find_hash(symname, sym_scope,
- (reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL),
- (reloc_type == R_PPC_COPY ? copyrel : symbolrel));
+ symbol_addr = (unsigned long) _dl_find_hash(symname, scope->dyn->symbol_scope,
+ elf_machine_type_class(reloc_type));
/*
* We want to allow undefined references to weak symbols - this might
* have been intentional. We should not be linking local symbols
if (delta<<6>>6 == delta) {
*reloc_addr = OPCODE_B(delta);
-#if 0
- /* this will almost never be true */
- } else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000) {
+ } else if (finaladdr <= 0x01fffffc) {
*reloc_addr = OPCODE_BA (finaladdr);
-#endif
} else {
/* Warning: we don't handle double-sized PLT entries */
Elf32_Word *plt, *data_words, index, offset;
_dl_dprintf(2, "%s ", _dl_reltypes(reloc_type));
#endif
if (symtab_index)
- _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
+ _dl_dprintf(2, "'%s'\n", symname);
return -1;
};
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_SH_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SH_COPY) * ELF_RTYPE_CLASS_COPY))
/* Get the address of the GOT entry */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
if (!new_addr) {
- new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
- if (new_addr) {
- return (unsigned long) new_addr;
- }
-
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
_dl_exit(1);
}
symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
- (reloc_type == R_SH_JMP_SLOT ? tpnt : NULL), symbolrel);
+ elf_machine_type_class(reloc_type));
/*
* We want to allow undefined references to weak symbols - this might
if (symtab_index) {
- symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
+ symbol_addr = (unsigned long) _dl_find_hash(symname, scope, ELF_RTYPE_CLASS_COPY);
if (!symbol_addr) goof++;
}
if (!goof) {
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_SH_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SH_COPY) * ELF_RTYPE_CLASS_COPY))
/* Get the address of the GOT entry */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver);
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
if (!new_addr) {
- new_addr = _dl_find_hash(symname, NULL, NULL, resolver);
-
- if (new_addr)
- return (unsigned long)new_addr;
-
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
_dl_progname, symname);
_dl_exit(1);
int stb;
symbol_addr = (unsigned long)_dl_find_hash(symname, scope,
- (reloc_type == R_SH_JMP_SLOT ? tpnt : NULL),
- symbolrel);
+ elf_machine_type_class(reloc_type));
/*
* We want to allow undefined references to weak symbols - this
if (symtab_index) {
symbol_addr = (unsigned long)
- _dl_find_hash(symname, scope, NULL, copyrel);
+ _dl_find_hash(symname, scope, ELF_RTYPE_CLASS_COPY);
if (!symbol_addr)
goof++;
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_type_class(type) \
+ ((((type) == R_SPARC_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY))
/* Get the address of the GOT entry */
new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope, tpnt, resolver);
+ tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
if(!new_addr) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
_dl_progname, strtab + symtab[symtab_index].st_name);
symbol_addr = (unsigned int)
_dl_find_hash(strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope,
- (reloc_type == R_SPARC_JMP_SLOT ? tpnt : NULL), symbolrel);
+ tpnt->symbol_scope, elf_machine_type_class(reloc_type);
if(!symbol_addr &&
ELF32_ST_BIND(symtab [symtab_index].st_info) == STB_GLOBAL) {
symbol_addr = (unsigned int)
_dl_find_hash(strtab + symtab[symtab_index].st_name,
- xpnt->next, NULL, copyrel);
+ xpnt->next, ELF_RTYPE_CLASS_COPY);
if(!symbol_addr) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
_dl_progname, strtab + symtab[symtab_index].st_name);
static int __attribute__ ((unused)) foobar1 = (int) foobar; /* Use as pointer */
extern void _dl_dprintf(int, const char *, ...) __attribute__ ((__weak__, __alias__ ("foobar")));
-extern char *_dl_find_hash(const char *, struct dyn_elf *, struct elf_resolve *, enum caller_type)
+extern char *_dl_find_hash(const char *, struct dyn_elf *, int)
__attribute__ ((__weak__, __alias__ ("foobar")));
extern struct elf_resolve * _dl_load_shared_library(int, struct dyn_elf **, struct elf_resolve *, char *, int)
__attribute__ ((__weak__, __alias__ ("foobar")));
if(_dl_debug)
_dl_dprintf(_dl_debug_file, "Trying to dlopen '%s'\n", (char*)libname);
#endif
+ if (!(tpnt = _dl_check_if_named_library_is_loaded((char *)libname, 0)))
tpnt = _dl_load_shared_library(0, &rpnt, tfrom, (char*)libname, 0);
if (tpnt == NULL) {
_dl_unmap_cache();
dpnt->d_un.d_val);
name = _dl_get_last_path_component(lpntstr);
+ if ((tpnt1 = _dl_check_if_named_library_is_loaded(name, 0)))
+ continue;
+
#ifdef __SUPPORT_LD_DEBUG__
if(_dl_debug)
_dl_dprintf(_dl_debug_file, "Trying to load '%s', needed by '%s'\n",
}
}
- ret = _dl_find_hash((char*)name, handle, NULL, copyrel);
+ ret = _dl_find_hash((char*)name, handle, 0);
/*
* Nothing found.