Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/ld.elf_so/arch/powerpc Resolve ADDR16_LO, ADDR16_HI,...
details: https://anonhg.NetBSD.org/src/rev/3709b79e3ed9
branches: trunk
changeset: 1005471:3709b79e3ed9
user: uwe <uwe%NetBSD.org@localhost>
date: Sun Dec 08 22:57:51 2019 +0000
description:
Resolve ADDR16_LO, ADDR16_HI, and ADDR16_HA relocs.
Recent GNU ld does not resolve them statically if the reloc is in a
writable section and the symbol is not already referenced from text.
diffstat:
libexec/ld.elf_so/arch/powerpc/ppc_reloc.c | 51 ++++++++++++++++++++++++++++-
1 files changed, 49 insertions(+), 2 deletions(-)
diffs (79 lines):
diff -r 1569a9a038e2 -r 3709b79e3ed9 libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
--- a/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Sun Dec 08 22:41:42 2019 +0000
+++ b/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Sun Dec 08 22:57:51 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ppc_reloc.c,v 1.58 2018/12/30 03:23:46 christos Exp $ */
+/* $NetBSD: ppc_reloc.c,v 1.59 2019/12/08 22:57:51 uwe Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: ppc_reloc.c,v 1.58 2018/12/30 03:23:46 christos Exp $");
+__RCSID("$NetBSD: ppc_reloc.c,v 1.59 2019/12/08 22:57:51 uwe Exp $");
#endif /* not lint */
#include <stdarg.h>
@@ -197,6 +197,9 @@
case R_TYPE(ADDR32): /* <address> S + A */
#endif
case R_TYPE(GLOB_DAT): /* <address> S + A */
+ case R_TYPE(ADDR16_LO):
+ case R_TYPE(ADDR16_HI):
+ case R_TYPE(ADDR16_HA):
case R_TYPE(DTPMOD):
case R_TYPE(DTPREL):
case R_TYPE(TPREL):
@@ -234,6 +237,50 @@
obj->path, (void *)*where, defobj->path));
break;
+ /*
+ * Recent GNU ld does not resolve ADDR16_{LO,HI,HA} if
+ * the reloc is in a writable section and the symbol
+ * is not already referenced from text.
+ */
+ case R_TYPE(ADDR16_LO): {
+ tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
+ rela->r_addend);
+
+ uint16_t tmp16 = (uint16_t)(tmp & 0xffff);
+
+ uint16_t *where16 = (uint16_t *)where;
+ if (*where16 != tmp16)
+ *where16 = tmp16;
+ rdbg(("ADDR16_LO %s in %s --> #lo(%p) = 0x%x in %s",
+ obj->strtab + obj->symtab[symnum].st_name,
+ obj->path, (void *)tmp, tmp16, defobj->path));
+ break;
+ }
+
+ case R_TYPE(ADDR16_HI):
+ case R_TYPE(ADDR16_HA): {
+ tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
+ rela->r_addend);
+
+ uint16_t tmp16 = (uint16_t)((tmp >> 16) & 0xffff);
+ if (ELF_R_TYPE(rela->r_info) == R_TYPE(ADDR16_HA)
+ && (tmp & 0x8000))
+ ++tmp16;
+
+ uint16_t *where16 = (uint16_t *)where;
+ if (*where16 != tmp16)
+ *where16 = tmp16;
+ rdbg(("ADDR16_H%c %s in %s --> #h%c(%p) = 0x%x in %s",
+ (ELF_R_TYPE(rela->r_info) == R_TYPE(ADDR16_HI)
+ ? 'I' : 'A'),
+ obj->strtab + obj->symtab[symnum].st_name,
+ obj->path,
+ (ELF_R_TYPE(rela->r_info) == R_TYPE(ADDR16_HI)
+ ? 'i' : 'a'),
+ (void *)tmp, tmp16, defobj->path));
+ break;
+ }
+
case R_TYPE(RELATIVE): /* <address> B + A */
*where = (Elf_Addr)(obj->relocbase + rela->r_addend);
rdbg(("RELATIVE in %s --> %p", obj->path,
Home |
Main Index |
Thread Index |
Old Index