diff --git a/lld/test/ELF/mips-eh_frame-pic.s b/lld/test/ELF/mips-eh_frame-pic.s --- a/lld/test/ELF/mips-eh_frame-pic.s +++ b/lld/test/ELF/mips-eh_frame-pic.s @@ -12,11 +12,11 @@ ## relative addressing. # NOPIC-ERR: ld.lld: error: can't create dynamic relocation R_MIPS_64 against local symbol in readonly segment -## For -fPIC, .eh_frame should contain DW_EH_PE_pcrel | DW_EH_PE_sdata4 values: +## For -fPIC, .eh_frame should contain DW_EH_PE_pcrel | DW_EH_PE_sdata8 values: # 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,12 +31,12 @@ # 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 0x0 # ABS64-RELOCS-NEXT: 0x1C R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE .text 0x0 -# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE - 0x0 +# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_64/R_MIPS_NONE - 0x0 # PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 - 0x0 # RELOCS-NEXT: } @@ -44,10 +44,10 @@ ## ^^ 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 -## ^^ 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) +# PIC32-EH-FRAME: Augmentation data: 1B +## ^^ fde pointer encoding: DW_EH_PE_pcrel | DW_EH_PE_sdata4 +# PIC64-EH-FRAME: Augmentation data: 1C +## ^^ fde pointer encoding: DW_EH_PE_pcrel | DW_EH_PE_sdata8 .ent func .global func diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -208,7 +208,7 @@ // 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 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -306,14 +306,11 @@ case Triple::mipsel: case Triple::mips64: 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) - FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - else - FDECFIEncoding = Ctx->getAsmInfo()->getCodePointerSize() == 4 - ? dwarf::DW_EH_PE_sdata4 - : dwarf::DW_EH_PE_sdata8; + FDECFIEncoding = Ctx->getAsmInfo()->getCodePointerSize() == 4 + ? dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_sdata8; + if (PositionIndependent) + FDECFIEncoding |= dwarf::DW_EH_PE_pcrel; break; case Triple::ppc64: case Triple::ppc64le: diff --git a/llvm/lib/Object/RelocationResolver.cpp b/llvm/lib/Object/RelocationResolver.cpp --- a/llvm/lib/Object/RelocationResolver.cpp +++ b/llvm/lib/Object/RelocationResolver.cpp @@ -291,6 +291,7 @@ static bool supportsMips32(uint64_t Type) { switch (Type) { case ELF::R_MIPS_32: + case ELF::R_MIPS_PC32: case ELF::R_MIPS_TLS_DTPREL32: return true; default: @@ -303,6 +304,8 @@ uint32_t Rel = R.getType(); if (Rel == ELF::R_MIPS_32) return (S + A) & 0xFFFFFFFF; + if (Rel == ELF::R_MIPS_PC32) + return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF; if (Rel == ELF::R_MIPS_TLS_DTPREL32) return (S + A) & 0xFFFFFFFF; llvm_unreachable("Invalid relocation type"); diff --git a/llvm/test/CodeGen/Mips/ehframe-indirect.ll b/llvm/test/CodeGen/Mips/ehframe-indirect.ll --- a/llvm/test/CodeGen/Mips/ehframe-indirect.ll +++ b/llvm/test/CodeGen/Mips/ehframe-indirect.ll @@ -1,32 +1,27 @@ ; RUN: llc -mtriple=mipsel-linux-gnu < %s -asm-verbose -relocation-model=pic | \ -; RUN: FileCheck -check-prefixes=ALL,LINUX,LINUX-O32,O32 %s +; RUN: FileCheck -check-prefixes=ALL,O32 %s ; RUN: llc -mtriple=mipsel-linux-android < %s -asm-verbose -relocation-model=pic | \ -; RUN: FileCheck -check-prefixes=ALL,LINUX,LINUX-O32,O32 %s +; RUN: FileCheck -check-prefixes=ALL,O32 %s ; RUN: llc -mtriple=mips64el-linux-gnu -target-abi=n32 < %s -asm-verbose -relocation-model=pic | \ -; RUN: FileCheck -check-prefixes=ALL,LINUX,LINUX-N32,N32 %s +; RUN: FileCheck -check-prefixes=ALL,N32 %s ; RUN: llc -mtriple=mips64el-linux-gnu < %s -asm-verbose -relocation-model=pic | \ -; RUN: FileCheck -check-prefixes=ALL,LINUX,LINUX-N64,N64 %s +; RUN: FileCheck -check-prefixes=ALL,N64 %s ; RUN: llc -mtriple=mips64el-linux-android < %s -asm-verbose -relocation-model=pic | \ -; RUN: FileCheck -check-prefixes=ALL,LINUX,LINUX-N64,N64 %s +; RUN: FileCheck -check-prefixes=ALL,N64 %s ; RUN: llc -mtriple=mips64el-linux-gnu < %s -asm-verbose -relocation-model=pic | \ -; RUN: FileCheck -check-prefixes=ALL,LINUX,LINUX-N64,N64 %s +; RUN: FileCheck -check-prefixes=ALL,N64 %s ; RUN: llc -mtriple=mips64-unknown-freebsd11.0 < %s -asm-verbose -relocation-model=pic | \ -; RUN: FileCheck -check-prefixes=ALL,FREEBSD,FREEBSD-N64,N64 %s +; RUN: FileCheck -check-prefixes=ALL,N64 %s @_ZTISt9exception = external constant i8* define i32 @main() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { ; 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 - -; FreeBSD can (and must) be more direct about the encodings it wants. -; FREEBSD: .cfi_personality 155, DW.ref.__gxx_personality_v0 -; FREEBSD-O32: .cfi_lsda 27, $exception0 -; FREEBSD-NEW: .cfi_lsda 27, .Lexception0 +; ALL: .cfi_personality 155, DW.ref.__gxx_personality_v0 +; O32: .cfi_lsda 27, $exception0 +; N32: .cfi_lsda 27, .Lexception0 +; N64: .cfi_lsda 27, .Lexception0 entry: invoke void @foo() to label %cont unwind label %lpad diff --git a/llvm/test/DebugInfo/Mips/eh_frame.ll b/llvm/test/DebugInfo/Mips/eh_frame.ll --- 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 00000000 DW.ref.__gxx_personality_v0 +; PIC-DAG: R_MIPS_PC32 ; PIC-DAG: R_MIPS_PC32 -; PIC-DAG: R_MIPS_32 00000000 .gcc_except_table ; 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 --- 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-NEXT %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-NEXT %s +// RUN: llvm-dwarfdump -eh-frame %t.o | FileCheck --check-prefixes=DWARF64,DWARF64_PIC %s func: .cfi_startproc @@ -51,7 +50,7 @@ // ABS32-NEXT: R_MIPS_32 // ABS64-NEXT: R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE // PIC32-NEXT: R_MIPS_PC32 -// PIC64-NEXT: R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE +// PIC64-NEXT: R_MIPS_PC32/R_MIPS_64/R_MIPS_NONE // RELOCS-NEXT: } // DWARF32: 00000000 00000010 00000000 CIE @@ -83,14 +82,14 @@ // DWARF64-NEXT: Return address column: 31 // DWARF64_ABS-NEXT: Augmentation data: 0C // ^^ fde pointer encoding: DW_EH_PE_sdata8 -// DWARF64_PIC: Augmentation data: 1B -// ^^ fde pointer encoding: DW_EH_PE_pcrel | DW_EH_PE_sdata4 +// DWARF64_PIC: Augmentation data: 1C +// ^^ fde pointer encoding: DW_EH_PE_pcrel | DW_EH_PE_sdata8 // DWARF64-EMPTY: // DWARF64-NEXT: DW_CFA_def_cfa_register: reg29 // DWARF64_PIC-NEXT: DW_CFA_nop: // // DWARF64_ABS: 00000014 00000018 00000018 FDE cie=00000000 pc=00000000...00000000 -// DWARF64_PIC: 00000014 00000010 00000018 FDE cie=00000000 pc=00000000...00000000 +// DWARF64_PIC: 00000014 00000018 00000018 FDE cie=00000000 pc=00000000...00000000 // DWARF64-NEXT: DW_CFA_nop: // DWARF64-NEXT: DW_CFA_nop: // DWARF64-NEXT: DW_CFA_nop: