Skip to content

Commit 8f21294

Browse files
authored
MIPS: Use pcrel|sdata4 for eh_frame (llvm#91291)
Gas uses encoding DW_EH_PE_absptr for PIC, and gnu ld converts it to DW_EH_PE_sdata4|DW_EH_PE_pcrel. LLD doesn't have this workarounding, thus complains ``` relocation R_MIPS_32 cannot be used against local symbol; recompile with -fPIC relocation R_MIPS_64 cannot be used against local symbol; recompile with -fPIC ``` So, let's generates asm/obj files with `DW_EH_PE_sdata4|DW_EH_PE_pcrel` encoding. In fact, GNU ld supports such OBJs well. For N64, maybe we should use sdata8, while GNU ld doesn't support it well, and in fact sdata4 is enough now. So we just ignore the `Large` for `MCObjectFileInfo::initELFMCObjectFileInfo`. Maybe we should switch back to sdata8 once GNU LD supports it well. Fixes: llvm#58377.
1 parent dd4bf22 commit 8f21294

File tree

6 files changed

+19
-18
lines changed

6 files changed

+19
-18
lines changed

lld/test/ELF/mips-eh_frame-pic.s

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux --position-independent %s -o %t-pic.o
1717
# RUN: llvm-readobj -r %t-pic.o | FileCheck %s --check-prefixes=RELOCS,PIC64-RELOCS
1818
# RUN: ld.lld -shared %t-pic.o -o %t-pic.so
19-
# RUN: llvm-dwarfdump --eh-frame %t-pic.so | FileCheck %s --check-prefix=PIC-EH-FRAME
19+
# RUN: llvm-dwarfdump --eh-frame %t-pic.so | FileCheck %s --check-prefix=PIC64-EH-FRAME
2020

2121
## Also check MIPS32:
2222
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-nopic32.o
@@ -31,7 +31,7 @@
3131
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux --position-independent %s -o %t-pic32.o
3232
# RUN: llvm-readobj -r %t-pic32.o | FileCheck %s --check-prefixes=RELOCS,PIC32-RELOCS
3333
# RUN: ld.lld -shared %t-pic32.o -o %t-pic32.so
34-
# RUN: llvm-dwarfdump --eh-frame %t-pic32.so | FileCheck %s --check-prefix=PIC-EH-FRAME
34+
# RUN: llvm-dwarfdump --eh-frame %t-pic32.so | FileCheck %s --check-prefix=PIC32-EH-FRAME
3535

3636
# RELOCS: .rel{{a?}}.eh_frame {
3737
# ABS32-RELOCS-NEXT: 0x1C R_MIPS_32 .text
@@ -44,7 +44,9 @@
4444
## ^^ fde pointer encoding: DW_EH_PE_sdata8
4545
# ABS32-EH-FRAME: Augmentation data: 0B
4646
## ^^ fde pointer encoding: DW_EH_PE_sdata4
47-
# PIC-EH-FRAME: Augmentation data: 1B
47+
# PIC32-EH-FRAME: Augmentation data: 1B
48+
## ^^ fde pointer encoding: DW_EH_PE_pcrel | DW_EH_PE_sdata4
49+
# PIC64-EH-FRAME: Augmentation data: 1B
4850
## ^^ fde pointer encoding: DW_EH_PE_pcrel | DW_EH_PE_sdata4
4951
## Note: ld.bfd converts the R_MIPS_64 relocs to DW_EH_PE_pcrel | DW_EH_PE_sdata8
5052
## for N64 ABI (and DW_EH_PE_pcrel | DW_EH_PE_sdata4 for MIPS32)

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,11 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
212212
// identify N64 from just a triple.
213213
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
214214
dwarf::DW_EH_PE_sdata4;
215-
// We don't support PC-relative LSDA references in GAS so we use the default
216-
// DW_EH_PE_absptr for those.
217215

218216
// FreeBSD must be explicit about the data size and using pcrel since it's
219217
// assembler/linker won't do the automatic conversion that the Linux tools
220218
// do.
221-
if (TgtM.getTargetTriple().isOSFreeBSD()) {
219+
if (isPositionIndependent() || TgtM.getTargetTriple().isOSFreeBSD()) {
222220
PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
223221
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
224222
}

llvm/lib/MC/MCObjectFileInfo.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,9 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
343343
case Triple::mips64el:
344344
// We cannot use DW_EH_PE_sdata8 for the large PositionIndependent case
345345
// since there is no R_MIPS_PC64 relocation (only a 32-bit version).
346-
if (PositionIndependent && !Large)
346+
// In fact DW_EH_PE_sdata4 is enough for us now, and GNU ld doesn't
347+
// support pcrel|sdata8 well. Let's use sdata4 for now.
348+
if (PositionIndependent)
347349
FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
348350
else
349351
FDECFIEncoding = Ctx->getAsmInfo()->getCodePointerSize() == 4

llvm/test/CodeGen/Mips/ehframe-indirect.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ define i32 @main() personality ptr @__gxx_personality_v0 {
1717
; ALL: .cfi_startproc
1818

1919
; Linux must rely on the assembler/linker converting the encodings.
20-
; LINUX: .cfi_personality 128, DW.ref.__gxx_personality_v0
21-
; LINUX-O32: .cfi_lsda 0, $exception0
22-
; LINUX-NEW: .cfi_lsda 0, .Lexception0
20+
; LINUX: .cfi_personality 155, DW.ref.__gxx_personality_v0
21+
; LINUX-O32: .cfi_lsda 27, $exception0
22+
; LINUX-NEW: .cfi_lsda 27, .Lexception0
2323

2424
; FreeBSD can (and must) be more direct about the encodings it wants.
2525
; FREEBSD: .cfi_personality 155, DW.ref.__gxx_personality_v0

llvm/test/DebugInfo/Mips/eh_frame.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
; STATIC-DAG: R_MIPS_32 00000000 .gcc_except_table
1818

1919
; PIC-LABEL: Relocation section '.rel.eh_frame'
20-
; PIC-DAG: R_MIPS_32 00000000 DW.ref.__gxx_personality_v0
21-
; PIC-DAG: R_MIPS_PC32
22-
; PIC-DAG: R_MIPS_32 00000000 .gcc_except_table
20+
; PIC-DAG: R_MIPS_PC32 00000000 DW.ref.__gxx_personality_v0
21+
; PIC-DAG: R_MIPS_PC32 00000000 .L0
22+
; PIC-DAG: R_MIPS_PC32 00000000 .L0
2323

2424
; CHECK-READELF: DW.ref.__gxx_personality_v0
2525
; CHECK-READELF-STATIC-NEXT: R_MIPS_32 00000000 .text

llvm/test/MC/Mips/eh-frame.s

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,13 @@
3333
// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,PIC64 %s
3434
// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_PIC %s
3535

36-
/// However using the large code model forces R_MIPS_64 since there is no R_MIPS_PC64 relocation:
3736
// RUN: llvm-mc -filetype=obj %s -o %t.o -triple mips64-unknown-linux-gnu --position-independent --large-code-model
38-
// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,ABS64 %s
39-
// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_ABS %s
37+
// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,PIC64 %s
38+
// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_PIC %s
4039

4140
// RUN: llvm-mc -filetype=obj %s -o %t.o -triple mips64el-unknown-linux-gnu --position-independent --large-code-model
42-
// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,ABS64 %s
43-
// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_ABS %s
41+
// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,PIC64 %s
42+
// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_PIC %s
4443

4544
func:
4645
.cfi_startproc

0 commit comments

Comments
 (0)