[uClibc] buildroot in an uClibc env
Joakim Tjernlund
joakim.tjernlund at lumentis.se
Thu Feb 12 19:07:20 UTC 2004
> Hello!
>
> I have successfully finished (almost) a buildroot in an uClibc env
> (minimal: busybox, tinylogin, gcc_3_3_target,
> binutils_target), only the
> last step running genext2fs segfaults (nothing changed in the main
> Makefile, all snapshots and buildroot are from 20040212 (unless the
> __LIBDL_SHARED__ changes in uClibc)
>
> Peter
Hi Peter
I have just sent Erik a few fixes for ldso(against current CVS).
You can try and see if it gets better.
I have only tested powerpc, but the arch changes were quite simple.
Jocke
Index: include/dl-elf.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/include/dl-elf.h,v
retrieving revision 1.9
diff -u -b -B -w -p -r1.9 dl-elf.h
--- include/dl-elf.h 10 Feb 2004 09:26:46 -0000 1.9
+++ include/dl-elf.h 12 Feb 2004 16:30:55 -0000
@@ -92,6 +92,19 @@ extern int _dl_fixup(struct dyn_elf *rpn
# 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
Index: include/dl-hash.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/include/dl-hash.h,v
retrieving revision 1.3
diff -u -b -B -w -p -r1.3 dl-hash.h
--- include/dl-hash.h 10 Feb 2004 11:47:57 -0000 1.3
+++ include/dl-hash.h 12 Feb 2004 16:30:55 -0000
@@ -67,9 +67,8 @@ extern struct elf_resolve * _dl_add_elf_
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);
Index: ldso/dl-elf.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/dl-elf.c,v
retrieving revision 1.65
diff -u -b -B -w -p -r1.65 dl-elf.c
--- ldso/dl-elf.c 10 Feb 2004 06:54:27 -0000 1.65
+++ ldso/dl-elf.c 12 Feb 2004 16:30:56 -0000
@@ -255,12 +255,13 @@ struct elf_resolve *_dl_load_shared_libr
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);
Index: ldso/dl-hash.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/dl-hash.c,v
retrieving revision 1.17
diff -u -b -B -w -p -r1.17 dl-hash.c
--- ldso/dl-hash.c 10 Feb 2004 11:47:57 -0000 1.17
+++ ldso/dl-hash.c 12 Feb 2004 16:30:56 -0000
@@ -154,7 +154,7 @@ struct elf_resolve *_dl_add_elf_hash_tab
* 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;
@@ -163,23 +163,12 @@ char *_dl_find_hash(const char *name, st
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 at 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
@@ -187,39 +176,35 @@ char *_dl_find_hash(const char *name, st
* 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;
/*
@@ -236,19 +221,25 @@ char *_dl_find_hash(const char *name, st
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;
Index: ldso/dl-startup.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/dl-startup.c,v
retrieving revision 1.5
diff -u -b -B -w -p -r1.5 dl-startup.c
--- ldso/dl-startup.c 10 Feb 2004 13:31:43 -0000 1.5
+++ ldso/dl-startup.c 12 Feb 2004 16:30:56 -0000
@@ -513,11 +513,10 @@ found_got:
/* 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) {
Index: ldso/ldso.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/ldso.c,v
retrieving revision 1.92
diff -u -b -B -w -p -r1.92 ldso.c
--- ldso/ldso.c 10 Feb 2004 13:31:43 -0000 1.92
+++ ldso/ldso.c 12 Feb 2004 16:30:56 -0000
@@ -609,12 +609,12 @@ void _dl_get_ready_to_run(struct elf_res
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;
@@ -638,10 +638,10 @@ void _dl_get_ready_to_run(struct elf_res
}
#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. */
Index: ldso/arm/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/arm/dl-sysdep.h,v
retrieving revision 1.7
diff -u -b -B -w -p -r1.7 dl-sysdep.h
--- ldso/arm/dl-sysdep.h 17 Dec 2003 08:05:40 -0000 1.7
+++ ldso/arm/dl-sysdep.h 12 Feb 2004 16:30:56 -0000
@@ -122,3 +122,11 @@ static inline unsigned long arm_modulus(
#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))
Index: ldso/arm/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/arm/elfinterp.c,v
retrieving revision 1.18
diff -u -b -B -w -p -r1.18 elfinterp.c
--- ldso/arm/elfinterp.c 29 Jan 2004 12:18:51 -0000 1.18
+++ ldso/arm/elfinterp.c 12 Feb 2004 16:30:56 -0000
@@ -148,7 +148,7 @@ unsigned long _dl_linux_resolver(struct
/* 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);
@@ -283,7 +283,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,s
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
@@ -424,7 +424,7 @@ _dl_do_copy_reloc (struct elf_resolve *t
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) {
Index: ldso/cris/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/cris/dl-sysdep.h,v
retrieving revision 1.4
diff -u -b -B -w -p -r1.4 dl-sysdep.h
--- ldso/cris/dl-sysdep.h 10 Feb 2004 09:26:48 -0000 1.4
+++ ldso/cris/dl-sysdep.h 12 Feb 2004 16:30:56 -0000
@@ -110,3 +110,19 @@ cris_mod(unsigned long m, unsigned long
#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))
Index: ldso/cris/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/cris/elfinterp.c,v
retrieving revision 1.7
diff -u -b -B -w -p -r1.7 elfinterp.c
--- ldso/cris/elfinterp.c 29 Jan 2004 12:18:51 -0000 1.7
+++ ldso/cris/elfinterp.c 12 Feb 2004 16:30:56 -0000
@@ -142,10 +142,10 @@ _dl_linux_resolver(struct elf_resolve *t
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);
+ new_addr = _dl_find_hash(symname, NULL, ELF_RTYPE_CLASS_PLT);
if (new_addr)
return (unsigned long) new_addr;
@@ -261,7 +261,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, s
}
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) {
@@ -366,7 +366,7 @@ _dl_do_copy_reloc(struct elf_resolve *tp
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++;
Index: ldso/i386/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/i386/dl-sysdep.h,v
retrieving revision 1.9
diff -u -b -B -w -p -r1.9 dl-sysdep.h
--- ldso/i386/dl-sysdep.h 17 Dec 2003 08:05:41 -0000 1.9
+++ ldso/i386/dl-sysdep.h 12 Feb 2004 16:30:56 -0000
@@ -79,3 +79,12 @@ extern unsigned long _dl_linux_resolver(
#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))
Index: ldso/i386/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/i386/elfinterp.c,v
retrieving revision 1.29
diff -u -b -B -w -p -r1.29 elfinterp.c
--- ldso/i386/elfinterp.c 7 Feb 2004 10:40:16 -0000 1.29
+++ ldso/i386/elfinterp.c 12 Feb 2004 16:30:56 -0000
@@ -145,9 +145,9 @@ unsigned long _dl_linux_resolver(struct
got_addr = (char **) instr_addr;
/* 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);
+ new_addr = _dl_find_hash(symname, NULL, ELF_RTYPE_CLASS_PLT);
if (new_addr) {
return (unsigned long) new_addr;
}
@@ -263,7 +263,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,s
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
@@ -377,7 +377,7 @@ _dl_do_copy_reloc (struct elf_resolve *t
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) {
Index: ldso/m68k/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/m68k/dl-sysdep.h,v
retrieving revision 1.4
diff -u -b -B -w -p -r1.4 dl-sysdep.h
--- ldso/m68k/dl-sysdep.h 17 Dec 2003 08:05:41 -0000 1.4
+++ ldso/m68k/dl-sysdep.h 12 Feb 2004 16:30:56 -0000
@@ -86,3 +86,11 @@ extern unsigned int _dl_linux_resolver (
#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))
Index: ldso/m68k/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/m68k/elfinterp.c,v
retrieving revision 1.15
diff -u -b -B -w -p -r1.15 elfinterp.c
--- ldso/m68k/elfinterp.c 29 Jan 2004 12:18:52 -0000 1.15
+++ ldso/m68k/elfinterp.c 12 Feb 2004 16:30:57 -0000
@@ -98,7 +98,7 @@ unsigned int _dl_linux_resolver (int dum
/* 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",
@@ -218,7 +218,7 @@ int _dl_parse_relocation_information(str
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
@@ -342,7 +342,7 @@ int _dl_parse_copy_information(struct dy
{
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",
Index: ldso/mips/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/mips/dl-sysdep.h,v
retrieving revision 1.7
diff -u -b -B -w -p -r1.7 dl-sysdep.h
--- ldso/mips/dl-sysdep.h 17 Dec 2003 08:05:42 -0000 1.7
+++ ldso/mips/dl-sysdep.h 12 Feb 2004 16:30:57 -0000
@@ -134,3 +134,5 @@ unsigned long _dl_linux_resolver(unsigne
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+
+#define elf_machine_type_class(type) ELF_RTYPE_CLASS_PLT
Index: ldso/mips/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/mips/elfinterp.c,v
retrieving revision 1.9
diff -u -b -B -w -p -r1.9 elfinterp.c
--- ldso/mips/elfinterp.c 5 Feb 2004 01:54:33 -0000 1.9
+++ ldso/mips/elfinterp.c 12 Feb 2004 16:30:57 -0000
@@ -129,7 +129,7 @@ unsigned long _dl_linux_resolver(unsigne
symname = strtab + sym->st_name;
new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
- tpnt->symbol_scope, tpnt, resolver);
+ tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
/* Address of jump instruction to fix up */
instr_addr = (unsigned long) (got + local_gotno + sym_index - gotsym);
@@ -279,12 +279,12 @@ void _dl_perform_mips_global_got_relocat
*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)
@@ -295,7 +295,7 @@ void _dl_perform_mips_global_got_relocat
}
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++;
Index: ldso/powerpc/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/powerpc/dl-sysdep.h,v
retrieving revision 1.9
diff -u -b -B -w -p -r1.9 dl-sysdep.h
--- ldso/powerpc/dl-sysdep.h 29 Jan 2004 08:20:11 -0000 1.9
+++ ldso/powerpc/dl-sysdep.h 12 Feb 2004 16:30:57 -0000
@@ -125,3 +125,16 @@ void _dl_init_got(unsigned long *lpnt,st
#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))
Index: ldso/powerpc/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/powerpc/elfinterp.c,v
retrieving revision 1.36
diff -u -b -B -w -p -r1.36 elfinterp.c
--- ldso/powerpc/elfinterp.c 31 Jan 2004 03:15:07 -0000 1.36
+++ ldso/powerpc/elfinterp.c 12 Feb 2004 16:30:57 -0000
@@ -210,7 +210,7 @@ unsigned long _dl_linux_resolver(struct
/* Get the address of the GOT entry */
finaladdr = (Elf32_Addr) _dl_find_hash(strtab + symtab[symtab_index].st_name,
- tpnt->symbol_scope, tpnt, resolver);
+ 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);
@@ -223,11 +223,8 @@ unsigned long _dl_linux_resolver(struct
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;
@@ -261,7 +258,6 @@ _dl_do_reloc (struct elf_resolve *tpnt,s
char *symname;
Elf32_Addr *reloc_addr;
Elf32_Addr finaladdr;
- struct dyn_elf *sym_scope;
unsigned long symbol_addr;
#if defined (__SUPPORT_LD_DEBUG__)
@@ -278,19 +274,8 @@ _dl_do_reloc (struct elf_resolve *tpnt,s
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
@@ -320,11 +305,8 @@ _dl_do_reloc (struct elf_resolve *tpnt,s
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;
Index: ldso/sh/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/sh/dl-sysdep.h,v
retrieving revision 1.8
diff -u -b -B -w -p -r1.8 dl-sysdep.h
--- ldso/sh/dl-sysdep.h 17 Dec 2003 08:05:43 -0000 1.8
+++ ldso/sh/dl-sysdep.h 12 Feb 2004 16:30:57 -0000
@@ -142,3 +142,12 @@ _dl_urem(unsigned int n, unsigned int ba
#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))
Index: ldso/sh/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/sh/elfinterp.c,v
retrieving revision 1.8
diff -u -b -B -w -p -r1.8 elfinterp.c
--- ldso/sh/elfinterp.c 29 Jan 2004 12:18:55 -0000 1.8
+++ ldso/sh/elfinterp.c 12 Feb 2004 16:30:57 -0000
@@ -149,9 +149,9 @@ unsigned long _dl_linux_resolver(struct
/* 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);
+ new_addr = _dl_find_hash(symname, NULL, ELF_RTYPE_CLASS_PLT);
if (new_addr) {
return (unsigned long) new_addr;
}
@@ -270,7 +270,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,s
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
@@ -385,7 +385,7 @@ _dl_do_copy_reloc (struct elf_resolve *t
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) {
Index: ldso/sh64/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/sh64/dl-sysdep.h,v
retrieving revision 1.1
diff -u -b -B -w -p -r1.1 dl-sysdep.h
--- ldso/sh64/dl-sysdep.h 17 Dec 2003 08:07:14 -0000 1.1
+++ ldso/sh64/dl-sysdep.h 12 Feb 2004 16:30:57 -0000
@@ -168,3 +168,11 @@ extern unsigned long _dl_linux_resolver(
#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))
Index: ldso/sh64/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/sh64/elfinterp.c,v
retrieving revision 1.2
diff -u -b -B -w -p -r1.2 elfinterp.c
--- ldso/sh64/elfinterp.c 29 Jan 2004 12:18:56 -0000 1.2
+++ ldso/sh64/elfinterp.c 12 Feb 2004 16:30:57 -0000
@@ -190,9 +190,9 @@ unsigned long _dl_linux_resolver(struct
/* 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);
+ new_addr = _dl_find_hash(symname, NULL, ELF_RTYPE_CLASS_PLT);
if (new_addr)
return (unsigned long)new_addr;
@@ -319,8 +319,7 @@ static int _dl_do_reloc(struct elf_resol
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
@@ -492,7 +491,7 @@ static int _dl_do_copy_reloc(struct elf_
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++;
Index: ldso/sparc/dl-sysdep.h
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/sparc/dl-sysdep.h,v
retrieving revision 1.5
diff -u -b -B -w -p -r1.5 dl-sysdep.h
--- ldso/sparc/dl-sysdep.h 17 Dec 2003 08:05:44 -0000 1.5
+++ ldso/sparc/dl-sysdep.h 12 Feb 2004 16:30:57 -0000
@@ -110,3 +110,11 @@ extern unsigned int _dl_linux_resolver(u
#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))
Index: ldso/sparc/elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/sparc/elfinterp.c,v
retrieving revision 1.14
diff -u -b -B -w -p -r1.14 elfinterp.c
--- ldso/sparc/elfinterp.c 29 Jan 2004 12:18:58 -0000 1.14
+++ ldso/sparc/elfinterp.c 12 Feb 2004 16:30:57 -0000
@@ -109,7 +109,7 @@ unsigned int _dl_linux_resolver(unsigned
/* 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);
@@ -225,8 +225,7 @@ int _dl_parse_relocation_information(str
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) {
@@ -343,7 +342,7 @@ int _dl_parse_copy_information(struct dy
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);
Index: libdl/libdl.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/libdl/libdl.c,v
retrieving revision 1.38
diff -u -b -B -w -p -r1.38 libdl.c
--- libdl/libdl.c 12 Feb 2004 08:51:21 -0000 1.38
+++ libdl/libdl.c 12 Feb 2004 16:30:57 -0000
@@ -30,7 +30,7 @@ static void __attribute__ ((unused)) foo
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")));
@@ -179,6 +179,7 @@ void *_dlopen(const char *libname, int f
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();
@@ -220,6 +221,9 @@ void *_dlopen(const char *libname, int f
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",
@@ -381,7 +385,7 @@ void *_dlsym(void *vhandle, const char *
}
}
- ret = _dl_find_hash((char*)name, handle, NULL, copyrel);
+ ret = _dl_find_hash((char*)name, handle, 0);
/*
* Nothing found.
More information about the uClibc
mailing list