Module Name: src Committed By: martin Date: Mon Dec 9 16:14:10 UTC 2019
Modified Files: src/libexec/ld.elf_so/arch/powerpc [netbsd-9]: ppc_reloc.c Log Message: Pull up following revision(s) (requested by uwe in ticket #535): libexec/ld.elf_so/arch/powerpc/ppc_reloc.c: revision 1.60 libexec/ld.elf_so/arch/powerpc/ppc_reloc.c: revision 1.59 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. Use existing lo() and hi() macros. Same object code is generated. To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.58.2.1 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.58 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.58.2.1 --- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.58 Sun Dec 30 03:23:46 2018 +++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Mon Dec 9 16:14:10 2019 @@ -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.58.2.1 2019/12/09 16:14:10 martin 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.58.2.1 2019/12/09 16:14:10 martin Exp $"); #endif /* not lint */ #include <stdarg.h> @@ -197,6 +197,9 @@ _rtld_relocate_nonplt_objects(Obj_Entry 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 @@ _rtld_relocate_nonplt_objects(Obj_Entry 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 = lo(tmp); + + 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 = hi(tmp); + if (ELF_R_TYPE(rela->r_info) == R_TYPE(ADDR16_HA) + && (tmp & __ha16)) + ++tmp16; /* adjust to ha(tmp) */ + + 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,