summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2010-10-22 04:43:04 +0000
committermarcel <marcel@FreeBSD.org>2010-10-22 04:43:04 +0000
commit7586e071c7fcc6712d76d00cfdb94fc5d194616c (patch)
tree3f98c616d590eac9c0e2a383ff929308c22fc26d /libexec
parent05dec1f02a8dca8e3b8452c6dc1a3af7b54a36ce (diff)
downloadFreeBSD-src-7586e071c7fcc6712d76d00cfdb94fc5d194616c.zip
FreeBSD-src-7586e071c7fcc6712d76d00cfdb94fc5d194616c.tar.gz
Unbreak ia64.
With r169630 I disabled symbol versioning because it broke rtld. With r211706 rtld got broken for ia64 & powerpc64. It was fixed for powerpc64 with r212497. In between, r211749 removed the exports table because the version script handled the exports. But wait, symbol versioning was disabled on ia64. With exports controlled by the version script and symbol versioning disabled, all symbols are exported and too many symbols bind to the definition in rtld. Let's just say that waird things happen. So, enable symbol versioning on ia64 and apply a work-around for the SIGSEGV that triggered r169630 to begin with: when rtld relocates itself, it comes across r_debug_state and for some reason can't find the definition. This causes a failure, relocation aborts and null pointers galore. The work-around is to ignore the missing definition when rtld is relocating itself and keep going. Maybe with the next binutils this will all go away. Maybe not, in which case I still need to figure out why r_debug_state cannot be found. BTW: r_debug_state is in the symbol map -- I don't think any other rtld symbols that rtld references are in the symbol map...
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/Makefile2
-rw-r--r--libexec/rtld-elf/ia64/reloc.c19
2 files changed, 16 insertions, 5 deletions
diff --git a/libexec/rtld-elf/Makefile b/libexec/rtld-elf/Makefile
index a798f3a..62aaaab 100644
--- a/libexec/rtld-elf/Makefile
+++ b/libexec/rtld-elf/Makefile
@@ -34,7 +34,6 @@ LDFLAGS+= -shared -Wl,-Bsymbolic
DPADD= ${LIBC_PIC}
LDADD= -lc_pic -lssp_nonshared
-.if ${MACHINE_CPUARCH} != "ia64"
.if ${MK_SYMVER} == "yes"
LIBCDIR= ${.CURDIR}/../../lib/libc
VERSION_DEF= ${LIBCDIR}/Versions.def
@@ -48,7 +47,6 @@ ${PROG}: ${VERSION_MAP}
SYMBOL_MAPS+= ${.CURDIR}/${RTLD_ARCH}/Symbol.map
.endif
.endif
-.endif
.sinclude "${.CURDIR}/${RTLD_ARCH}/Makefile.inc"
diff --git a/libexec/rtld-elf/ia64/reloc.c b/libexec/rtld-elf/ia64/reloc.c
index 9a8d067..728fe30 100644
--- a/libexec/rtld-elf/ia64/reloc.c
+++ b/libexec/rtld-elf/ia64/reloc.c
@@ -195,9 +195,22 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
int sym_index;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache);
- if (def == NULL)
- return -1;
+ true, cache);
+ if (def == NULL) {
+ /*
+ * XXX r_debug_state is problematic and find_symdef()
+ * returns NULL for it. This probably has something to
+ * do with symbol versioning (r_debug_state is in the
+ * symbol map). If we return -1 in that case we abort
+ * relocating rtld, which typically is fatal. So, for
+ * now just skip the symbol when we're relocating
+ * rtld. We don't care about r_debug_state unless we
+ * are being debugged.
+ */
+ if (obj != obj_rtld)
+ return -1;
+ break;
+ }
if (def->st_shndx != SHN_UNDEF) {
target = (Elf_Addr)(defobj->relocbase + def->st_value);
OpenPOWER on IntegriCloud