Date: Tue, 4 Feb 2020 02:06:21 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r357484 - stable/12/sys/arm64/arm64 Message-ID: <202002040206.01426Lf3013941@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Tue Feb 4 02:06:21 2020 New Revision: 357484 URL: https://svnweb.freebsd.org/changeset/base/357484 Log: MFC r356947: Add relocation handling required for -zifunc-noplt to work on arm64. Modified: stable/12/sys/arm64/arm64/elf_machdep.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/arm64/arm64/elf_machdep.c ============================================================================== --- stable/12/sys/arm64/arm64/elf_machdep.c Tue Feb 4 01:09:02 2020 (r357483) +++ stable/12/sys/arm64/arm64/elf_machdep.c Tue Feb 4 02:06:21 2020 (r357484) @@ -122,6 +122,23 @@ elf_is_ifunc_reloc(Elf_Size r_info __unused) } static int +reloc_instr_imm(Elf32_Addr *where, Elf_Addr val, u_int msb, u_int lsb) +{ + + /* Check bounds: upper bits must be all ones or all zeros. */ + if ((uint64_t)((int64_t)val >> (msb + 1)) + 1 > 1) + return (-1); + val >>= lsb; + val &= (1 << (msb - lsb + 1)) - 1; + *where |= (Elf32_Addr)val; + return (0); +} + +/* + * Process a relocation. Support for some static relocations is required + * in order for the -zifunc-noplt optimization to work. + */ +static int elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, int local, elf_lookup_fn lookup) { @@ -156,10 +173,33 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbas return (0); } + error = 0; switch (rtype) { case R_AARCH64_NONE: case R_AARCH64_RELATIVE: break; + case R_AARCH64_TSTBR14: + error = lookup(lf, symidx, 1, &addr); + if (error != 0) + return (-1); + error = reloc_instr_imm((Elf32_Addr *)where, + addr + addend - (Elf_Addr)where, 15, 2); + break; + case R_AARCH64_CONDBR19: + error = lookup(lf, symidx, 1, &addr); + if (error != 0) + return (-1); + error = reloc_instr_imm((Elf32_Addr *)where, + addr + addend - (Elf_Addr)where, 20, 2); + break; + case R_AARCH64_JUMP26: + case R_AARCH64_CALL26: + error = lookup(lf, symidx, 1, &addr); + if (error != 0) + return (-1); + error = reloc_instr_imm((Elf32_Addr *)where, + addr + addend - (Elf_Addr)where, 27, 2); + break; case R_AARCH64_ABS64: case R_AARCH64_GLOB_DAT: case R_AARCH64_JUMP_SLOT: @@ -178,7 +218,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbas printf("kldload: unexpected relocation type %d\n", rtype); return (-1); } - return (0); + return (error); } int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002040206.01426Lf3013941>