Date: Thu, 18 Jan 2024 22:25:56 GMT From: John Baldwin <jhb@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 7ea7498f6406 - stable/14 - kldxref: Reduce divergence between per-architecture files Message-ID: <202401182225.40IMPulK089341@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=7ea7498f6406bec488957e3ec23ec4c89fa3c436 commit 7ea7498f6406bec488957e3ec23ec4c89fa3c436 Author: Jessica Clarke <jrtc27@FreeBSD.org> AuthorDate: 2023-12-14 20:17:20 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2024-01-18 21:30:57 +0000 kldxref: Reduce divergence between per-architecture files Note that relbase is always 0 for DSOs so its omission for __KLD_SHARED architectures was not a bug in practice. Whilst here, also parenthesise the dest offset for where to avoid transiently creating an out-of-bounds pointer, which is UB (though even on CHERI architectures, where capability bounds compression can result in that creating invalid capabilities that will trap on dereference, optimisation will reassociate to the correct form in practice and thus work just fine). (cherry picked from commit 2a622f14e8a588de654847ae264cdc3616528c9d) --- usr.sbin/kldxref/ef_aarch64.c | 22 +++++++++++++--------- usr.sbin/kldxref/ef_amd64.c | 28 ++++++++++++---------------- usr.sbin/kldxref/ef_arm.c | 12 ++++++------ usr.sbin/kldxref/ef_i386.c | 17 ++++++++--------- usr.sbin/kldxref/ef_mips.c | 29 +++++++++++++---------------- usr.sbin/kldxref/ef_powerpc.c | 39 +++++++++++++++++++++------------------ usr.sbin/kldxref/ef_riscv.c | 15 ++++++++++----- 7 files changed, 83 insertions(+), 79 deletions(-) diff --git a/usr.sbin/kldxref/ef_aarch64.c b/usr.sbin/kldxref/ef_aarch64.c index 4365a7ff1f66..b61de3b032ab 100644 --- a/usr.sbin/kldxref/ef_aarch64.c +++ b/usr.sbin/kldxref/ef_aarch64.c @@ -47,21 +47,25 @@ ef_aarch64_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, GElf_Size rtype, symidx; const GElf_Rela *rela; - if (reltype != ELF_T_RELA) + switch (reltype) { + case ELF_T_RELA: + rela = (const GElf_Rela *)reldata; + where = (char *)dest + (relbase + rela->r_offset - dataoff); + addend = rela->r_addend; + rtype = GELF_R_TYPE(rela->r_info); + symidx = GELF_R_SYM(rela->r_info); + break; + default: return (EINVAL); - - rela = (const GElf_Rela *)reldata; - where = (char *)dest - dataoff + rela->r_offset; - addend = rela->r_addend; - rtype = GELF_R_TYPE(rela->r_info); - symidx = GELF_R_SYM(rela->r_info); + } if (where < (char *)dest || where >= (char *)dest + len) return (0); - switch(rtype) { + switch (rtype) { case R_AARCH64_RELATIVE: - le64enc(where, relbase + addend); + addr = relbase + addend; + le64enc(where, addr); break; case R_AARCH64_ABS64: addr = EF_SYMADDR(ef, symidx) + addend; diff --git a/usr.sbin/kldxref/ef_amd64.c b/usr.sbin/kldxref/ef_amd64.c index 729039daa509..fde032dcabc2 100644 --- a/usr.sbin/kldxref/ef_amd64.c +++ b/usr.sbin/kldxref/ef_amd64.c @@ -36,17 +36,16 @@ #include "ef.h" /* - * Apply relocations to the values we got from the file. `relbase' is the - * target relocation address of the section, and `dataoff' is the target - * relocation address of the data in `dest'. + * Apply relocations to the values obtained from the file. `relbase' is the + * target relocation address of the section, and `dataoff/len' is the region + * that is to be relocated, and has been copied to *dest */ static int ef_amd64_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest) { char *where; - GElf_Addr val; - GElf_Addr addend, addr; + GElf_Addr addr, addend; GElf_Size rtype, symidx; const GElf_Rel *rel; const GElf_Rela *rela; @@ -54,14 +53,14 @@ ef_amd64_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, switch (reltype) { case ELF_T_REL: rel = (const GElf_Rel *)reldata; - where = (char *)dest + relbase + rel->r_offset - dataoff; + where = (char *)dest + (relbase + rel->r_offset - dataoff); addend = 0; rtype = GELF_R_TYPE(rel->r_info); symidx = GELF_R_SYM(rel->r_info); break; case ELF_T_RELA: rela = (const GElf_Rela *)reldata; - where = (char *)dest + relbase + rela->r_offset - dataoff; + where = (char *)dest + (relbase + rela->r_offset - dataoff); addend = rela->r_addend; rtype = GELF_R_TYPE(rela->r_info); symidx = GELF_R_SYM(rela->r_info); @@ -90,23 +89,20 @@ ef_amd64_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, case R_X86_64_NONE: /* none */ break; case R_X86_64_64: /* S + A */ - addr = EF_SYMADDR(ef, symidx); - val = addr + addend; - le64enc(where, val); + addr = EF_SYMADDR(ef, symidx) + addend; + le64enc(where, addr); break; case R_X86_64_32S: /* S + A sign extend */ - addr = EF_SYMADDR(ef, symidx); - val = (Elf32_Addr)(addr + addend); - le32enc(where, val); + addr = EF_SYMADDR(ef, symidx) + addend; + le32enc(where, addr); break; case R_X86_64_GLOB_DAT: /* S */ addr = EF_SYMADDR(ef, symidx); le64enc(where, addr); break; case R_X86_64_RELATIVE: /* B + A */ - addr = addend + relbase; - val = addr; - le64enc(where, val); + addr = relbase + addend; + le64enc(where, addr); break; default: warnx("unhandled relocation type %d", (int)rtype); diff --git a/usr.sbin/kldxref/ef_arm.c b/usr.sbin/kldxref/ef_arm.c index 4b926839ee5d..cc5e265f821e 100644 --- a/usr.sbin/kldxref/ef_arm.c +++ b/usr.sbin/kldxref/ef_arm.c @@ -37,9 +37,9 @@ #include "ef.h" /* - * Apply relocations to the values we got from the file. `relbase' is the - * target relocation address of the section, and `dataoff' is the target - * relocation address of the data in `dest'. + * Apply relocations to the values obtained from the file. `relbase' is the + * target relocation address of the section, and `dataoff/len' is the region + * that is to be relocated, and has been copied to *dest */ static int ef_arm_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, @@ -54,14 +54,14 @@ ef_arm_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, switch (reltype) { case ELF_T_REL: rel = (const GElf_Rel *)reldata; - where = (char *)dest + relbase + rel->r_offset - dataoff; + where = (char *)dest + (relbase + rel->r_offset - dataoff); addend = 0; rtype = GELF_R_TYPE(rel->r_info); symidx = GELF_R_SYM(rel->r_info); break; case ELF_T_RELA: rela = (const GElf_Rela *)reldata; - where = (char *)dest + relbase + rela->r_offset - dataoff; + where = (char *)dest + (relbase + rela->r_offset - dataoff); addend = rela->r_addend; rtype = GELF_R_TYPE(rela->r_info); symidx = GELF_R_SYM(rela->r_info); @@ -82,7 +82,7 @@ ef_arm_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, le32enc(where, addr); break; case R_ARM_RELATIVE: /* B + A */ - addr = addend + relbase; + addr = relbase + addend; le32enc(where, addr); break; default: diff --git a/usr.sbin/kldxref/ef_i386.c b/usr.sbin/kldxref/ef_i386.c index e4f73877c430..962ed2bc0664 100644 --- a/usr.sbin/kldxref/ef_i386.c +++ b/usr.sbin/kldxref/ef_i386.c @@ -36,9 +36,9 @@ #include "ef.h" /* - * Apply relocations to the values we got from the file. `relbase' is the - * target relocation address of the section, and `dataoff' is the target - * relocation address of the data in `dest'. + * Apply relocations to the values obtained from the file. `relbase' is the + * target relocation address of the section, and `dataoff/len' is the region + * that is to be relocated, and has been copied to *dest */ static int ef_i386_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, @@ -53,14 +53,14 @@ ef_i386_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, switch (reltype) { case ELF_T_REL: rel = (const GElf_Rel *)reldata; - where = (char *)dest + relbase + rel->r_offset - dataoff; + where = (char *)dest + (relbase + rel->r_offset - dataoff); addend = 0; rtype = GELF_R_TYPE(rel->r_info); symidx = GELF_R_SYM(rel->r_info); break; case ELF_T_RELA: rela = (const GElf_Rela *)reldata; - where = (char *)dest + relbase + rela->r_offset - dataoff; + where = (char *)dest + (relbase + rela->r_offset - dataoff); addend = rela->r_addend; rtype = GELF_R_TYPE(rela->r_info); symidx = GELF_R_SYM(rela->r_info); @@ -76,13 +76,12 @@ ef_i386_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, addend = le32dec(where); switch (rtype) { - case R_386_RELATIVE: /* A + B */ - addr = addend + relbase; + case R_386_RELATIVE: /* B + A */ + addr = relbase + addend; le32enc(where, addr); break; case R_386_32: /* S + A - P */ - addr = EF_SYMADDR(ef, symidx); - addr += addend; + addr = EF_SYMADDR(ef, symidx) + addend; le32enc(where, addr); break; case R_386_GLOB_DAT: /* S */ diff --git a/usr.sbin/kldxref/ef_mips.c b/usr.sbin/kldxref/ef_mips.c index 60fd35390d7e..e4aeedb5c08b 100644 --- a/usr.sbin/kldxref/ef_mips.c +++ b/usr.sbin/kldxref/ef_mips.c @@ -39,32 +39,31 @@ #include "ef.h" /* - * Apply relocations to the values we got from the file. `relbase' is the - * target relocation address of the section, and `dataoff' is the target - * relocation address of the data in `dest'. + * Apply relocations to the values obtained from the file. `relbase' is the + * target relocation address of the section, and `dataoff/len' is the region + * that is to be relocated, and has been copied to *dest */ static int ef_mips_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest) { char *where; - GElf_Addr val; + GElf_Addr addr, addend; + GElf_Size rtype, symidx; const GElf_Rel *rel; const GElf_Rela *rela; - GElf_Addr addend, addr; - GElf_Size rtype, symidx; switch (reltype) { case ELF_T_REL: rel = (const GElf_Rel *)reldata; - where = (char *)dest + relbase + rel->r_offset - dataoff; + where = (char *)dest + (relbase + rel->r_offset - dataoff); addend = 0; rtype = GELF_R_TYPE(rel->r_info); symidx = GELF_R_SYM(rel->r_info); break; case ELF_T_RELA: rela = (const GElf_Rela *)reldata; - where = (char *)dest + relbase + rela->r_offset - dataoff; + where = (char *)dest + (relbase + rela->r_offset - dataoff); addend = rela->r_addend; rtype = GELF_R_TYPE(rela->r_info); symidx = GELF_R_SYM(rela->r_info); @@ -92,20 +91,18 @@ ef_mips_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, switch (rtype) { case R_MIPS_64: /* S + A */ - addr = EF_SYMADDR(ef, symidx); - val = addr + addend; + addr = EF_SYMADDR(ef, symidx) + addend; if (elf_encoding(ef) == ELFDATA2LSB) - le64enc(where, val); + le64enc(where, addr); else - be64enc(where, val); + be64enc(where, addr); break; case R_MIPS_32: /* S + A */ - addr = EF_SYMADDR(ef, symidx); - val = addr + addend; + addr = EF_SYMADDR(ef, symidx) + addend; if (elf_encoding(ef) == ELFDATA2LSB) - le32enc(where, val); + le32enc(where, addr); else - be32enc(where, val); + be32enc(where, addr); break; default: warnx("unhandled relocation type %d", (int)rtype); diff --git a/usr.sbin/kldxref/ef_powerpc.c b/usr.sbin/kldxref/ef_powerpc.c index ab33e170b488..f72cc1d85e20 100644 --- a/usr.sbin/kldxref/ef_powerpc.c +++ b/usr.sbin/kldxref/ef_powerpc.c @@ -40,48 +40,51 @@ * target relocation address of the section, and `dataoff/len' is the region * that is to be relocated, and has been copied to *dest */ -int +static int ef_ppc_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest) { char *where; - GElf_Addr addend, val; + GElf_Addr addr, addend; GElf_Size rtype, symidx; const GElf_Rela *rela; - if (reltype != ELF_T_RELA) + switch (reltype) { + case ELF_T_RELA: + rela = (const GElf_Rela *)reldata; + where = (char *)dest + (relbase + rela->r_offset - dataoff); + addend = rela->r_addend; + rtype = GELF_R_TYPE(rela->r_info); + symidx = GELF_R_SYM(rela->r_info); + break; + default: return (EINVAL); - - rela = (const GElf_Rela *)reldata; - where = (char *)dest - dataoff + rela->r_offset; - addend = rela->r_addend; - rtype = GELF_R_TYPE(rela->r_info); - symidx = GELF_R_SYM(rela->r_info); + } if (where < (char *)dest || where >= (char *)dest + len) return (0); switch (rtype) { case R_PPC_RELATIVE: /* word32|doubleword64 B + A */ - val = relbase + addend; + addr = relbase + addend; if (elf_class(ef) == ELFCLASS64) { if (elf_encoding(ef) == ELFDATA2LSB) - le64enc(where, val); + le64enc(where, addr); else - be64enc(where, val); + be64enc(where, addr); } else - be32enc(where, val); + be32enc(where, addr); break; case R_PPC_ADDR32: /* word32 S + A */ - val = EF_SYMADDR(ef, symidx) + addend; - be32enc(where, val); + addr = EF_SYMADDR(ef, symidx) + addend; + be32enc(where, addr); break; case R_PPC64_ADDR64: /* doubleword64 S + A */ - val = EF_SYMADDR(ef, symidx) + addend; + addr = EF_SYMADDR(ef, symidx) + addend; if (elf_encoding(ef) == ELFDATA2LSB) - le64enc(where, val); + le64enc(where, addr); else - be64enc(where, val); + be64enc(where, addr); break; default: warnx("unhandled relocation type %d", (int)rtype); diff --git a/usr.sbin/kldxref/ef_riscv.c b/usr.sbin/kldxref/ef_riscv.c index 38299a1e9b46..46b9b66bee58 100644 --- a/usr.sbin/kldxref/ef_riscv.c +++ b/usr.sbin/kldxref/ef_riscv.c @@ -38,19 +38,24 @@ #include "ef.h" -int +/* + * Apply relocations to the values obtained from the file. `relbase' is the + * target relocation address of the section, and `dataoff/len' is the region + * that is to be relocated, and has been copied to *dest + */ +static int ef_riscv_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest) { char *where; - const GElf_Rela *rela; - GElf_Addr addend, addr; + GElf_Addr addr, addend; GElf_Size rtype, symidx; + const GElf_Rela *rela; switch (reltype) { case ELF_T_RELA: rela = (const GElf_Rela *)reldata; - where = (char *)dest + relbase + rela->r_offset - dataoff; + where = (char *)dest + (relbase + rela->r_offset - dataoff); addend = rela->r_addend; rtype = GELF_R_TYPE(rela->r_info); symidx = GELF_R_SYM(rela->r_info); @@ -68,7 +73,7 @@ ef_riscv_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype, le64enc(where, addr); break; case R_RISCV_RELATIVE: /* B + A */ - addr = addend + relbase; + addr = relbase + addend; le64enc(where, addr); break; default:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202401182225.40IMPulK089341>