diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp index 9682b4722ac1e..7e6f14a7cc8f4 100644 --- a/lld/ELF/Arch/LoongArch.cpp +++ b/lld/ELF/Arch/LoongArch.cpp @@ -1579,7 +1579,8 @@ bool LoongArch::relaxOnce(int pass) const { if (!(osec->flags & SHF_EXECINSTR)) continue; for (InputSection *sec : getInputSections(*osec, storage)) - changed |= relax(ctx, *sec); + if (sec->relaxAux) + changed |= relax(ctx, *sec); } return changed; } @@ -1591,6 +1592,8 @@ void LoongArch::finalizeRelax(int passes) const { if (!(osec->flags & SHF_EXECINSTR)) continue; for (InputSection *sec : getInputSections(*osec, storage)) { + if (!sec->relaxAux) + continue; RelaxAux &aux = *sec->relaxAux; if (!aux.relocDeltas) continue; diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index bdb728bc19e7b..4c2bca27e1047 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -706,6 +706,8 @@ void elf::initSymbolAnchors(Ctx &ctx) { if (!(osec->flags & SHF_EXECINSTR)) continue; for (InputSection *sec : getInputSections(*osec, storage)) { + if (isa(sec)) + continue; sec->relaxAux = make(); if (sec->relocs().size()) { sec->relaxAux->relocDeltas = @@ -750,6 +752,8 @@ void elf::initSymbolAnchors(Ctx &ctx) { if (!(osec->flags & SHF_EXECINSTR)) continue; for (InputSection *sec : getInputSections(*osec, storage)) { + if (!sec->relaxAux) + continue; llvm::sort(sec->relaxAux->anchors, [](auto &a, auto &b) { return std::make_pair(a.offset, a.end) < std::make_pair(b.offset, b.end); @@ -980,7 +984,8 @@ bool RISCV::relaxOnce(int pass) const { if (!(osec->flags & SHF_EXECINSTR)) continue; for (InputSection *sec : getInputSections(*osec, storage)) - changed |= relax(ctx, pass, *sec); + if (sec->relaxAux) + changed |= relax(ctx, pass, *sec); } return changed; } @@ -1104,6 +1109,8 @@ void RISCV::finalizeRelax(int passes) const { if (!(osec->flags & SHF_EXECINSTR)) continue; for (InputSection *sec : getInputSections(*osec, storage)) { + if (!sec->relaxAux) + continue; RelaxAux &aux = *sec->relaxAux; if (!aux.relocDeltas) continue; diff --git a/lld/test/ELF/loongarch-relax-synthetic-in-text.s b/lld/test/ELF/loongarch-relax-synthetic-in-text.s new file mode 100644 index 0000000000000..67c355e5a7595 --- /dev/null +++ b/lld/test/ELF/loongarch-relax-synthetic-in-text.s @@ -0,0 +1,31 @@ +# REQUIRES: loongarch +# RUN: rm -rf %t && split-file %s %t +# RUN: llvm-mc --filetype=obj -triple=loongarch64 -mattr=+relax %t/a.s -o %t/a.o + +## Do not crash when we encounter a synthetic section (like .got) that has +## been placed inside an executable output section via a linker script. +## Synthetic sections do not have relaxAux data structures initialized. + +# RUN: ld.lld -T %t/a.ld %t/a.o -o %t/a.out +# RUN: llvm-objdump -s %t/a.out | FileCheck %s + +# CHECK: Contents of section .text: +# CHECK-NEXT: 0400001a 8440c002 10000000 00000000 + +#--- a.s +.global _start +_start: + pcalau12i $a0, %got_pc_hi20(sym) + ld.d $a0, $a0, %got_pc_lo12(sym) + +.data +sym: + .word 0 + +#--- a.ld +SECTIONS { + .text : { + *(.text) + *(.got) + } +} diff --git a/lld/test/ELF/riscv-relax-synthetic-in-text.s b/lld/test/ELF/riscv-relax-synthetic-in-text.s new file mode 100644 index 0000000000000..d892da3fdd3a4 --- /dev/null +++ b/lld/test/ELF/riscv-relax-synthetic-in-text.s @@ -0,0 +1,33 @@ +# REQUIRES: riscv +# RUN: rm -rf %t && split-file %s %t +# RUN: llvm-mc --filetype=obj -triple=riscv64 -mattr=+relax %t/a.s -o %t/a.o + +## Do not crash when we encounter a synthetic section (like .got) that has +## been placed inside an executable output section via a linker script. +## Synthetic sections do not have relaxAux data structures initialized. + +# RUN: ld.lld -T %t/a.ld %t/a.o -o %t/a.out +# RUN: llvm-objdump -s %t/a.out | FileCheck %s + +# CHECK: Contents of section .text: +# CHECK-NEXT: 17050000 03350501 00000000 00000000 +# CHECK-NEXT: 18000000 00000000 + +#--- a.s +.global _start +_start: +1: + auipc a0, %got_pcrel_hi(sym) + ld a0, %pcrel_lo(1b)(a0) + +.data +sym: + .word 0 + +#--- a.ld +SECTIONS { + .text : { + *(.text) + *(.got) + } +}