[lld] 8f21294 - MIPS: Use pcrel|sdata4 for eh_frame (#91291)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 8 02:30:18 PDT 2024
Author: YunQiang Su
Date: 2024-05-08T17:30:14+08:00
New Revision: 8f21294897befee48f9f72734ea1b0ad4c920aa0
URL: https://github.com/llvm/llvm-project/commit/8f21294897befee48f9f72734ea1b0ad4c920aa0
DIFF: https://github.com/llvm/llvm-project/commit/8f21294897befee48f9f72734ea1b0ad4c920aa0.diff
LOG: MIPS: Use pcrel|sdata4 for eh_frame (#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: #58377.
Added:
Modified:
lld/test/ELF/mips-eh_frame-pic.s
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/lib/MC/MCObjectFileInfo.cpp
llvm/test/CodeGen/Mips/ehframe-indirect.ll
llvm/test/DebugInfo/Mips/eh_frame.ll
llvm/test/MC/Mips/eh-frame.s
Removed:
################################################################################
diff --git a/lld/test/ELF/mips-eh_frame-pic.s b/lld/test/ELF/mips-eh_frame-pic.s
index c04dbdf57b08a..79076e74a7e3f 100644
--- a/lld/test/ELF/mips-eh_frame-pic.s
+++ b/lld/test/ELF/mips-eh_frame-pic.s
@@ -16,7 +16,7 @@
# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux --position-independent %s -o %t-pic.o
# RUN: llvm-readobj -r %t-pic.o | FileCheck %s --check-prefixes=RELOCS,PIC64-RELOCS
# RUN: ld.lld -shared %t-pic.o -o %t-pic.so
-# RUN: llvm-dwarfdump --eh-frame %t-pic.so | FileCheck %s --check-prefix=PIC-EH-FRAME
+# RUN: llvm-dwarfdump --eh-frame %t-pic.so | FileCheck %s --check-prefix=PIC64-EH-FRAME
## Also check MIPS32:
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-nopic32.o
@@ -31,7 +31,7 @@
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux --position-independent %s -o %t-pic32.o
# RUN: llvm-readobj -r %t-pic32.o | FileCheck %s --check-prefixes=RELOCS,PIC32-RELOCS
# RUN: ld.lld -shared %t-pic32.o -o %t-pic32.so
-# RUN: llvm-dwarfdump --eh-frame %t-pic32.so | FileCheck %s --check-prefix=PIC-EH-FRAME
+# RUN: llvm-dwarfdump --eh-frame %t-pic32.so | FileCheck %s --check-prefix=PIC32-EH-FRAME
# RELOCS: .rel{{a?}}.eh_frame {
# ABS32-RELOCS-NEXT: 0x1C R_MIPS_32 .text
@@ -44,7 +44,9 @@
## ^^ fde pointer encoding: DW_EH_PE_sdata8
# ABS32-EH-FRAME: Augmentation data: 0B
## ^^ fde pointer encoding: DW_EH_PE_sdata4
-# PIC-EH-FRAME: Augmentation data: 1B
+# PIC32-EH-FRAME: Augmentation data: 1B
+## ^^ fde pointer encoding: DW_EH_PE_pcrel | DW_EH_PE_sdata4
+# PIC64-EH-FRAME: Augmentation data: 1B
## ^^ fde pointer encoding: DW_EH_PE_pcrel | DW_EH_PE_sdata4
## Note: ld.bfd converts the R_MIPS_64 relocs to DW_EH_PE_pcrel | DW_EH_PE_sdata8
## for N64 ABI (and DW_EH_PE_pcrel | DW_EH_PE_sdata4 for MIPS32)
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 622773cc73f78..3e1897ce670a6 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -212,13 +212,11 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
// identify N64 from just a triple.
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
- // We don't support PC-relative LSDA references in GAS so we use the default
- // DW_EH_PE_absptr for those.
// FreeBSD must be explicit about the data size and using pcrel since it's
// assembler/linker won't do the automatic conversion that the Linux tools
// do.
- if (TgtM.getTargetTriple().isOSFreeBSD()) {
+ if (isPositionIndependent() || TgtM.getTargetTriple().isOSFreeBSD()) {
PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 1f8f8ec557275..045b566aae783 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -343,7 +343,9 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
case Triple::mips64el:
// We cannot use DW_EH_PE_sdata8 for the large PositionIndependent case
// since there is no R_MIPS_PC64 relocation (only a 32-bit version).
- if (PositionIndependent && !Large)
+ // In fact DW_EH_PE_sdata4 is enough for us now, and GNU ld doesn't
+ // support pcrel|sdata8 well. Let's use sdata4 for now.
+ if (PositionIndependent)
FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
else
FDECFIEncoding = Ctx->getAsmInfo()->getCodePointerSize() == 4
diff --git a/llvm/test/CodeGen/Mips/ehframe-indirect.ll b/llvm/test/CodeGen/Mips/ehframe-indirect.ll
index e36fa2f9ce423..1cd2b86a8e158 100644
--- a/llvm/test/CodeGen/Mips/ehframe-indirect.ll
+++ b/llvm/test/CodeGen/Mips/ehframe-indirect.ll
@@ -17,9 +17,9 @@ define i32 @main() personality ptr @__gxx_personality_v0 {
; ALL: .cfi_startproc
; Linux must rely on the assembler/linker converting the encodings.
-; LINUX: .cfi_personality 128, DW.ref.__gxx_personality_v0
-; LINUX-O32: .cfi_lsda 0, $exception0
-; LINUX-NEW: .cfi_lsda 0, .Lexception0
+; LINUX: .cfi_personality 155, DW.ref.__gxx_personality_v0
+; LINUX-O32: .cfi_lsda 27, $exception0
+; LINUX-NEW: .cfi_lsda 27, .Lexception0
; FreeBSD can (and must) be more direct about the encodings it wants.
; FREEBSD: .cfi_personality 155, DW.ref.__gxx_personality_v0
diff --git a/llvm/test/DebugInfo/Mips/eh_frame.ll b/llvm/test/DebugInfo/Mips/eh_frame.ll
index 60d4dc76777eb..d53bc156ef29f 100644
--- a/llvm/test/DebugInfo/Mips/eh_frame.ll
+++ b/llvm/test/DebugInfo/Mips/eh_frame.ll
@@ -17,9 +17,9 @@
; STATIC-DAG: R_MIPS_32 00000000 .gcc_except_table
; PIC-LABEL: Relocation section '.rel.eh_frame'
-; PIC-DAG: R_MIPS_32 00000000 DW.ref.__gxx_personality_v0
-; PIC-DAG: R_MIPS_PC32
-; PIC-DAG: R_MIPS_32 00000000 .gcc_except_table
+; PIC-DAG: R_MIPS_PC32 00000000 DW.ref.__gxx_personality_v0
+; PIC-DAG: R_MIPS_PC32 00000000 .L0
+; PIC-DAG: R_MIPS_PC32 00000000 .L0
; CHECK-READELF: DW.ref.__gxx_personality_v0
; CHECK-READELF-STATIC-NEXT: R_MIPS_32 00000000 .text
diff --git a/llvm/test/MC/Mips/eh-frame.s b/llvm/test/MC/Mips/eh-frame.s
index fd145317bf4d6..dac142325f9fd 100644
--- a/llvm/test/MC/Mips/eh-frame.s
+++ b/llvm/test/MC/Mips/eh-frame.s
@@ -33,14 +33,13 @@
// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,PIC64 %s
// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_PIC %s
-/// However using the large code model forces R_MIPS_64 since there is no R_MIPS_PC64 relocation:
// RUN: llvm-mc -filetype=obj %s -o %t.o -triple mips64-unknown-linux-gnu --position-independent --large-code-model
-// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,ABS64 %s
-// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_ABS %s
+// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,PIC64 %s
+// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_PIC %s
// RUN: llvm-mc -filetype=obj %s -o %t.o -triple mips64el-unknown-linux-gnu --position-independent --large-code-model
-// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,ABS64 %s
-// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_ABS %s
+// RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS,PIC64 %s
+// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_PIC %s
func:
.cfi_startproc
More information about the llvm-commits
mailing list