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