From 732f4bc7c4baa7546b0942f69562d4fb3f474999 Mon Sep 17 00:00:00 2001 From: Jack Carter Date: Mon, 1 Apr 2013 21:55:15 +0000 Subject: [PATCH] Mips direct object exception handling regression Revision 177141 caused a regression in all but mips64 little endian. That is because none of the other Mips targets had test cases checking the contents of the .eh_frame section. This patch fixes both the llvm code and adds an assembler test case to include the current 4 flavors. The test cases unfortunately rely on llvm-objdump. A preferable method would be to use a pretty printer output such as what readelf -wf would give. I also changed the name of the test case to correct a typo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178506 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELF.h | 57 +++++++++++++++++++++++++++++++++++++ lib/MC/MCObjectFileInfo.cpp | 7 +++-- test/MC/Mips/eh-frame.s | 46 ++++++++++++++++++++++++++++++ test/MC/Mips/fde-reloc.s | 21 ++++++++++++++ 4 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 test/MC/Mips/eh-frame.s create mode 100644 test/MC/Mips/fde-reloc.s diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 7ab3643b798..b0d8663b7d9 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -1634,6 +1634,63 @@ error_code ELFObjectFile::getRelocationTypeName( res = "Unknown"; } break; + case ELF::EM_MIPS: + switch (type) { + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NONE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_26); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LITERAL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT5); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT6); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_DISP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_PAGE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_OFST); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SUB); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_A); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_B); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_DELETE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHER); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHEST); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SCN_DISP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_ADD_IMMEDIATE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PJUMP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_RELGOT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JALR); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_LDM); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GOTTPREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT); + default: + res = "Unknown"; + } + break; case ELF::EM_AARCH64: switch (type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_NONE); diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index bafa002e3d4..0d32ad40e80 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -223,9 +223,10 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { } void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { - // FIXME: Check this. Mips64el is using the base values, which is most likely - // incorrect. - if (T.getArch() != Triple::mips64el) + if (T.getArch() != Triple::mips && + T.getArch() != Triple::mipsel && + T.getArch() != Triple::mips64 && + T.getArch() != Triple::mips64el ) FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; if (T.getArch() == Triple::x86) { diff --git a/test/MC/Mips/eh-frame.s b/test/MC/Mips/eh-frame.s new file mode 100644 index 00000000000..56278b8b99b --- /dev/null +++ b/test/MC/Mips/eh-frame.s @@ -0,0 +1,46 @@ +// Assembler generated object test. +// This tests .eh_frame descriptors minimally. + +// What we really need is a prettyprinter output check not unlike what +// gnu's readobj generates instead of checking the bits for .eh_frame. + +// RUN: llvm-mc -filetype=obj -mcpu=mips32r2 -triple mipsel-unknown-linux -arch=mipsel %s -o - \ +// RUN: | llvm-objdump -s - | FileCheck -check-prefix=CHECK-LEO32 %s + +// RUN: llvm-mc -filetype=obj -mcpu=mips32r2 -triple mips-unknown-linux -arch=mips %s -o - \ +// RUN: | llvm-objdump -s - | FileCheck -check-prefix=CHECK-BEO32 %s + +// RUN: llvm-mc -filetype=obj -mcpu=mips64r2 -mattr=n64 -arch=mips64el %s -o - \ +// RUN: | llvm-objdump -s - | FileCheck -check-prefix=CHECK-LE64 %s + +// RUN: llvm-mc -filetype=obj -mcpu=mips64r2 -mattr=n64 -arch=mips64 %s -o - \ +// RUN: | llvm-objdump -s - | FileCheck -check-prefix=CHECK-BE64 %s + +// O32 little endian +// CHECK-LEO32: Contents of section .eh_frame: +// CHECK-LEO32-NEXT: 0000 10000000 00000000 017a5200 017c1f01 .........zR..|.. +// CHECK-LEO32-NEXT: 0010 000c1d00 10000000 18000000 00000000 ................ +// CHECK-LEO32-NEXT: 0020 00000000 00000000 ........ + +// O32 big endian +// CHECK-BEO32: Contents of section .eh_frame: +// CHECK-BEO32-NEXT 0000 00000010 00000000 017a5200 017c1f01 .........zR..|.. +// CHECK-BEO32-NEXT 0010 000c1d00 00000010 00000018 00000000 ................ +// CHECK-BEO32-NEXT 0020 00000000 00000000 ........ + +// N64 little endian +// CHECK-LE64: Contents of section .eh_frame: +// CHECK-LE64-NEXT: 0000 10000000 00000000 017a5200 01781f01 .........zR..x.. +// CHECK-LE64-NEXT: 0010 000c1d00 18000000 18000000 00000000 ................ +// CHECK-LE64-NEXT: 0020 00000000 00000000 00000000 00000000 ................ + +// N64 big endian +// CHECK-BE64: Contents of section .eh_frame: +// CHECK-BE64-NEXT: 0000 00000010 00000000 017a5200 01781f01 .........zR..x.. +// CHECK-BE64-NEXT: 0010 000c1d00 00000018 00000018 00000000 ................ +// CHECK-BE64-NEXT: 0020 00000000 00000000 00000000 00000000 ................ + +func: + .cfi_startproc + .cfi_endproc + diff --git a/test/MC/Mips/fde-reloc.s b/test/MC/Mips/fde-reloc.s new file mode 100644 index 00000000000..2db5d0b638f --- /dev/null +++ b/test/MC/Mips/fde-reloc.s @@ -0,0 +1,21 @@ +// This just tests that a relocation of the specified type shows up as the first +// relocation in the relocation section for .eh_frame when produced by the +// assembler. + +// RUN: llvm-mc -filetype=obj %s -o - -triple mips-unknown-unknown | \ +// RUN: llvm-objdump -r - | FileCheck --check-prefix=MIPS32 %s + +// RUN: llvm-mc -filetype=obj %s -o - -triple mips64-unknown-unknown | \ +// RUN: llvm-objdump -r - | FileCheck --check-prefix=MIPS64 %s + +// PR15448 + +func: + .cfi_startproc + .cfi_endproc + +// MIPS32: RELOCATION RECORDS FOR [.eh_frame]: +// MIPS32-NEXT: R_MIPS_32 + +// MIPS64: RELOCATION RECORDS FOR [.eh_frame]: +// MIPS64-NEXT: R_MIPS_64