diff --git a/elf/arch-alpha.cc b/elf/arch-alpha.cc index d71894342e..751556f659 100644 --- a/elf/arch-alpha.cc +++ b/elf/arch-alpha.cc @@ -318,7 +318,7 @@ void AlphaGotSection::copy_buf(Context &ctx) { if (e.sym->is_imported) { *buf = ctx.arg.apply_dynamic_relocs ? e.addend : 0; - *dynrel++ = ElfRel(P, E::R_ABS, e.sym->get_dynsym_idx(ctx), e.addend); + *dynrel++ = ElfRel(P, E::R_DYNAMIC, e.sym->get_dynsym_idx(ctx), e.addend); } else { *buf = e.sym->get_addr(ctx) + e.addend; if (ctx.arg.pic && !e.sym->is_absolute()) diff --git a/elf/arch-mips64.cc b/elf/arch-mips64.cc index 4e4b476560..c81a31601d 100644 --- a/elf/arch-mips64.cc +++ b/elf/arch-mips64.cc @@ -57,6 +57,7 @@ void EhFrameSection::apply_eh_reloc(Context &ctx, const ElfRel &rel, case R_NONE: break; case R_MIPS_64: + assert(rel.r_type2 == R_NONE); *(U64 *)loc = val; break; default: @@ -84,11 +85,11 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) { Symbol &sym = *file.symbols[rel.r_sym]; u8 *loc = base + rel.r_offset; - [[maybe_unused]] auto check = [&](i64 val, i64 lo, i64 hi) { + auto check = [&](i64 val, i64 lo, i64 hi) { if (val < lo || hi <= val) Error(ctx) << *this << ": relocation " << rel << " against " << sym << " out of range: " << val << " is not in [" - << lo << ", " << hi << ")"; + << lo << ", " << hi << "); recompile with -mxgot"; }; auto write_combined = [&](u64 val) { @@ -114,19 +115,25 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) { }; auto write_hi16 = [&](u64 val) { + check(val, -(1LL << 31), 1LL << 31); if (rel.r_type2 == R_NONE && rel.r_type3 == R_NONE) *(U32 *)loc |= ((val + BIAS) >> 16) & 0xffff; else write_combined(val); }; - auto write_lo16 = [&](u64 val) { + auto write_lo16_nc = [&](u64 val) { if (rel.r_type2 == R_NONE && rel.r_type3 == R_NONE) *(U32 *)loc |= val & 0xffff; else write_combined(val); }; + auto write_lo16 = [&](u64 val) { + check(val, -(1 << 15), 1 << 15); + write_lo16_nc(val); + }; + u64 S = sym.get_addr(ctx); u64 A = rel.r_addend; u64 P = get_addr() + rel.r_offset; @@ -139,9 +146,9 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) { break; case R_MIPS_GPREL16: if (sym.is_local(ctx)) - write_lo16(S + A + GP0 - GP); + write_lo16_nc(S + A + GP0 - GP); else - write_lo16(S + A - GP); + write_lo16_nc(S + A - GP); break; case R_MIPS_GPREL32: write32(S + A + GP0 - GP); @@ -165,7 +172,7 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) { write_lo16(ctx.extra.got->get_gotpage_got_addr(ctx, sym, A) - GP); break; case R_MIPS_GOT_OFST: - write_lo16(S + A - ctx.extra.got->get_gotpage_page_addr(ctx, sym, A)); + write_lo16(0); break; case R_MIPS_JALR: break; @@ -173,7 +180,7 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) { write_hi16(S + A - ctx.tp_addr); break; case R_MIPS_TLS_TPREL_LO16: - write_lo16(S + A - ctx.tp_addr); + write_lo16_nc(S + A - ctx.tp_addr); break; case R_MIPS_TLS_GOTTPREL: write_lo16(sym.get_gottp_addr(ctx) - GP); @@ -182,13 +189,13 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) { write_hi16(S + A - ctx.dtp_addr); break; case R_MIPS_TLS_DTPREL_LO16: - write_lo16(S + A - ctx.dtp_addr); + write_lo16_nc(S + A - ctx.dtp_addr); break; case R_MIPS_TLS_GD: - write_lo16(sym.get_tlsgd_addr(ctx) + A - GP); + write_lo16(sym.get_tlsgd_addr(ctx) - GP); break; case R_MIPS_TLS_LDM: - write_lo16(ctx.got->get_tlsld_addr(ctx) + A - GP); + write_lo16(ctx.got->get_tlsld_addr(ctx) - GP); break; default: unreachable(); @@ -356,7 +363,7 @@ MipsGotSection::get_got_entries(Context &ctx) const { for (const SymbolAddend &ent : got_syms) { // If a symbol is imported, let the dynamic linker to resolve it. if (ent.sym->is_imported) { - add({0, E::R_GLOB_DAT, ent.sym}); + add({0, E::R_DYNAMIC, ent.sym}); continue; } diff --git a/elf/cmdline.cc b/elf/cmdline.cc index ba21fde9e2..31068db90d 100644 --- a/elf/cmdline.cc +++ b/elf/cmdline.cc @@ -428,7 +428,7 @@ std::vector parse_nonpositional_args(Context &ctx) { // It looks like the SPARC's dynamic linker takes both RELA's r_addend // and the value at the relocated place. So we don't want to write // values to relocated places. - if (is_sparc) + if constexpr (is_sparc) ctx.arg.apply_dynamic_relocs = false; auto read_arg = [&](std::string name) { @@ -1216,12 +1216,14 @@ std::vector parse_nonpositional_args(Context &ctx) { Fatal(ctx) << "-auxiliary may not be used without -shared"; } - if (!ctx.arg.apply_dynamic_relocs && !E::is_rela) - Fatal(ctx) << "--no-apply-dynamic-relocs may not be used on " - << E::target_name; + if constexpr (!E::is_rela || is_mips) + if (!ctx.arg.apply_dynamic_relocs) + Fatal(ctx) << "--no-apply-dynamic-relocs may not be used on " + << E::target_name; - if (is_sparc && ctx.arg.apply_dynamic_relocs) - Fatal(ctx) << "--apply-dynamic-relocs may not be used on SPARC64"; + if constexpr (is_sparc) + if (ctx.arg.apply_dynamic_relocs) + Fatal(ctx) << "--apply-dynamic-relocs may not be used on SPARC64"; if (!ctx.arg.section_start.empty() && !ctx.arg.section_order.empty()) Fatal(ctx) << "--section-start may not be used with --section-order"; diff --git a/elf/elf.h b/elf/elf.h index 0f6bc3cf23..2c3c64cc88 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -1866,6 +1866,7 @@ struct X86_64 { static constexpr u32 R_GLOB_DAT = R_X86_64_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_X86_64_JUMP_SLOT; static constexpr u32 R_ABS = R_X86_64_64; + static constexpr u32 R_DYNAMIC = R_X86_64_64; static constexpr u32 R_RELATIVE = R_X86_64_RELATIVE; static constexpr u32 R_IRELATIVE = R_X86_64_IRELATIVE; static constexpr u32 R_DTPOFF = R_X86_64_DTPOFF64; @@ -1889,6 +1890,7 @@ struct I386 { static constexpr u32 R_GLOB_DAT = R_386_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_386_JUMP_SLOT; static constexpr u32 R_ABS = R_386_32; + static constexpr u32 R_DYNAMIC = R_386_32; static constexpr u32 R_RELATIVE = R_386_RELATIVE; static constexpr u32 R_IRELATIVE = R_386_IRELATIVE; static constexpr u32 R_DTPOFF = R_386_TLS_DTPOFF32; @@ -1914,6 +1916,7 @@ struct ARM64 { static constexpr u32 R_GLOB_DAT = R_AARCH64_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_AARCH64_JUMP_SLOT; static constexpr u32 R_ABS = R_AARCH64_ABS64; + static constexpr u32 R_DYNAMIC = R_AARCH64_ABS64; static constexpr u32 R_RELATIVE = R_AARCH64_RELATIVE; static constexpr u32 R_IRELATIVE = R_AARCH64_IRELATIVE; static constexpr u32 R_DTPOFF = R_AARCH64_TLS_DTPREL64; @@ -1939,6 +1942,7 @@ struct ARM32 { static constexpr u32 R_GLOB_DAT = R_ARM_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_ARM_JUMP_SLOT; static constexpr u32 R_ABS = R_ARM_ABS32; + static constexpr u32 R_DYNAMIC = R_ARM_ABS32; static constexpr u32 R_RELATIVE = R_ARM_RELATIVE; static constexpr u32 R_IRELATIVE = R_ARM_IRELATIVE; static constexpr u32 R_DTPOFF = R_ARM_TLS_DTPOFF32; @@ -1962,6 +1966,7 @@ struct RV64LE { static constexpr u32 R_GLOB_DAT = R_RISCV_64; static constexpr u32 R_JUMP_SLOT = R_RISCV_JUMP_SLOT; static constexpr u32 R_ABS = R_RISCV_64; + static constexpr u32 R_DYNAMIC = R_RISCV_64; static constexpr u32 R_RELATIVE = R_RISCV_RELATIVE; static constexpr u32 R_IRELATIVE = R_RISCV_IRELATIVE; static constexpr u32 R_DTPOFF = R_RISCV_TLS_DTPREL64; @@ -1984,6 +1989,7 @@ struct RV64BE { static constexpr u32 R_GLOB_DAT = R_RISCV_64; static constexpr u32 R_JUMP_SLOT = R_RISCV_JUMP_SLOT; static constexpr u32 R_ABS = R_RISCV_64; + static constexpr u32 R_DYNAMIC = R_RISCV_64; static constexpr u32 R_RELATIVE = R_RISCV_RELATIVE; static constexpr u32 R_IRELATIVE = R_RISCV_IRELATIVE; static constexpr u32 R_DTPOFF = R_RISCV_TLS_DTPREL64; @@ -2006,6 +2012,7 @@ struct RV32LE { static constexpr u32 R_GLOB_DAT = R_RISCV_32; static constexpr u32 R_JUMP_SLOT = R_RISCV_JUMP_SLOT; static constexpr u32 R_ABS = R_RISCV_32; + static constexpr u32 R_DYNAMIC = R_RISCV_32; static constexpr u32 R_RELATIVE = R_RISCV_RELATIVE; static constexpr u32 R_IRELATIVE = R_RISCV_IRELATIVE; static constexpr u32 R_DTPOFF = R_RISCV_TLS_DTPREL32; @@ -2028,6 +2035,7 @@ struct RV32BE { static constexpr u32 R_GLOB_DAT = R_RISCV_32; static constexpr u32 R_JUMP_SLOT = R_RISCV_JUMP_SLOT; static constexpr u32 R_ABS = R_RISCV_32; + static constexpr u32 R_DYNAMIC = R_RISCV_32; static constexpr u32 R_RELATIVE = R_RISCV_RELATIVE; static constexpr u32 R_IRELATIVE = R_RISCV_IRELATIVE; static constexpr u32 R_DTPOFF = R_RISCV_TLS_DTPREL32; @@ -2052,6 +2060,7 @@ struct PPC32 { static constexpr u32 R_GLOB_DAT = R_PPC_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_PPC_JMP_SLOT; static constexpr u32 R_ABS = R_PPC_ADDR32; + static constexpr u32 R_DYNAMIC = R_PPC_ADDR32; static constexpr u32 R_RELATIVE = R_PPC_RELATIVE; static constexpr u32 R_IRELATIVE = R_PPC_IRELATIVE; static constexpr u32 R_DTPOFF = R_PPC_DTPREL32; @@ -2075,6 +2084,7 @@ struct PPC64V1 { static constexpr u32 R_GLOB_DAT = R_PPC64_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_PPC64_JMP_SLOT; static constexpr u32 R_ABS = R_PPC64_ADDR64; + static constexpr u32 R_DYNAMIC = R_PPC64_ADDR64; static constexpr u32 R_RELATIVE = R_PPC64_RELATIVE; static constexpr u32 R_IRELATIVE = R_PPC64_IRELATIVE; static constexpr u32 R_DTPOFF = R_PPC64_DTPREL64; @@ -2099,6 +2109,7 @@ struct PPC64V2 { static constexpr u32 R_GLOB_DAT = R_PPC64_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_PPC64_JMP_SLOT; static constexpr u32 R_ABS = R_PPC64_ADDR64; + static constexpr u32 R_DYNAMIC = R_PPC64_ADDR64; static constexpr u32 R_RELATIVE = R_PPC64_RELATIVE; static constexpr u32 R_IRELATIVE = R_PPC64_IRELATIVE; static constexpr u32 R_DTPOFF = R_PPC64_DTPREL64; @@ -2121,6 +2132,7 @@ struct S390X { static constexpr u32 R_GLOB_DAT = R_390_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_390_JMP_SLOT; static constexpr u32 R_ABS = R_390_64; + static constexpr u32 R_DYNAMIC = R_390_64; static constexpr u32 R_RELATIVE = R_390_RELATIVE; static constexpr u32 R_IRELATIVE = R_390_IRELATIVE; static constexpr u32 R_DTPOFF = R_390_TLS_DTPOFF; @@ -2143,6 +2155,7 @@ struct SPARC64 { static constexpr u32 R_GLOB_DAT = R_SPARC_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_SPARC_JMP_SLOT; static constexpr u32 R_ABS = R_SPARC_64; + static constexpr u32 R_DYNAMIC = R_SPARC_64; static constexpr u32 R_RELATIVE = R_SPARC_RELATIVE; static constexpr u32 R_IRELATIVE = R_SPARC_IRELATIVE; static constexpr u32 R_DTPOFF = R_SPARC_TLS_DTPOFF64; @@ -2165,6 +2178,7 @@ struct M68K { static constexpr u32 R_GLOB_DAT = R_68K_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_68K_JMP_SLOT; static constexpr u32 R_ABS = R_68K_32; + static constexpr u32 R_DYNAMIC = R_68K_32; static constexpr u32 R_RELATIVE = R_68K_RELATIVE; static constexpr u32 R_DTPOFF = R_68K_TLS_DTPREL32; static constexpr u32 R_TPOFF = R_68K_TLS_TPREL32; @@ -2186,6 +2200,7 @@ struct SH4 { static constexpr u32 R_GLOB_DAT = R_SH_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_SH_JMP_SLOT; static constexpr u32 R_ABS = R_SH_DIR32; + static constexpr u32 R_DYNAMIC = R_SH_DIR32; static constexpr u32 R_RELATIVE = R_SH_RELATIVE; static constexpr u32 R_DTPOFF = R_SH_TLS_DTPOFF32; static constexpr u32 R_TPOFF = R_SH_TLS_TPOFF32; @@ -2207,6 +2222,7 @@ struct ALPHA { static constexpr u32 R_GLOB_DAT = R_ALPHA_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_ALPHA_JMP_SLOT; static constexpr u32 R_ABS = R_ALPHA_REFQUAD; + static constexpr u32 R_DYNAMIC = R_ALPHA_REFQUAD; static constexpr u32 R_RELATIVE = R_ALPHA_RELATIVE; static constexpr u32 R_DTPOFF = R_ALPHA_DTPREL64; static constexpr u32 R_TPOFF = R_ALPHA_TPREL64; @@ -2227,7 +2243,8 @@ struct MIPS64LE { static constexpr u32 R_COPY = R_MIPS_COPY; static constexpr u32 R_GLOB_DAT = R_MIPS_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_MIPS_JUMP_SLOT; - static constexpr u32 R_ABS = R_MIPS_GLOB_DAT; + static constexpr u32 R_ABS = R_MIPS_64; + static constexpr u32 R_DYNAMIC = R_MIPS_REL32; static constexpr u32 R_RELATIVE = R_MIPS_REL32; static constexpr u32 R_DTPOFF = R_MIPS_TLS_DTPREL64; static constexpr u32 R_TPOFF = R_MIPS_TLS_TPREL64; @@ -2248,7 +2265,8 @@ struct MIPS64BE { static constexpr u32 R_COPY = R_MIPS_COPY; static constexpr u32 R_GLOB_DAT = R_MIPS_GLOB_DAT; static constexpr u32 R_JUMP_SLOT = R_MIPS_JUMP_SLOT; - static constexpr u32 R_ABS = R_MIPS_GLOB_DAT; + static constexpr u32 R_ABS = R_MIPS_64; + static constexpr u32 R_DYNAMIC = R_MIPS_REL32; static constexpr u32 R_RELATIVE = R_MIPS_REL32; static constexpr u32 R_DTPOFF = R_MIPS_TLS_DTPREL64; static constexpr u32 R_TPOFF = R_MIPS_TLS_TPREL64; diff --git a/elf/input-sections.cc b/elf/input-sections.cc index 9f07075dcc..7bcf03bb0c 100644 --- a/elf/input-sections.cc +++ b/elf/input-sections.cc @@ -322,7 +322,7 @@ static void apply_absrel(Context &ctx, InputSection &isec, bool writable = (isec.shdr().sh_flags & SHF_WRITE); auto emit_abs_dynrel = [&] { - *dynrel++ = ElfRel(P, E::R_ABS, sym.get_dynsym_idx(ctx), A); + *dynrel++ = ElfRel(P, E::R_DYNAMIC, sym.get_dynsym_idx(ctx), A); if (ctx.arg.apply_dynamic_relocs) *(Word *)loc = A; };