summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2015-06-18 15:05:15 +0000
committerJames Y Knight <jyknight@google.com>2015-06-18 15:05:15 +0000
commitf90346f8f6ebd4ce4589ba070e4baaeede80988a (patch)
treed42569f06e42c11e8915b81a6789d0c50cbded83
parent3645149ea23ed708f08a333065327307dda1221e (diff)
downloadbcm5719-llvm-f90346f8f6ebd4ce4589ba070e4baaeede80988a.tar.gz
bcm5719-llvm-f90346f8f6ebd4ce4589ba070e4baaeede80988a.zip
[SPARC] Repair GOT references to internal symbols.
They had been getting emitted as a section + offset reference, which is bogus since the value needs to be the offset within the GOT, not the actual address of the symbol's object. Differential Revision: http://reviews.llvm.org/D10441 llvm-svn: 240020
-rw-r--r--llvm/include/llvm/Support/ELFRelocs/Sparc.def4
-rw-r--r--llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp9
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp25
-rw-r--r--llvm/test/CodeGen/SPARC/obj-relocs.ll36
-rw-r--r--llvm/test/MC/Sparc/sparc-pic.s15
5 files changed, 69 insertions, 20 deletions
diff --git a/llvm/include/llvm/Support/ELFRelocs/Sparc.def b/llvm/include/llvm/Support/ELFRelocs/Sparc.def
index d6772ea675d..7e01a4a8a0a 100644
--- a/llvm/include/llvm/Support/ELFRelocs/Sparc.def
+++ b/llvm/include/llvm/Support/ELFRelocs/Sparc.def
@@ -83,7 +83,7 @@ ELF_RELOC(R_SPARC_TLS_DTPOFF64, 77)
ELF_RELOC(R_SPARC_TLS_TPOFF32, 78)
ELF_RELOC(R_SPARC_TLS_TPOFF64, 79)
ELF_RELOC(R_SPARC_GOTDATA_HIX22, 80)
-ELF_RELOC(R_SPARC_GOTDATA_LOX22, 81)
+ELF_RELOC(R_SPARC_GOTDATA_LOX10, 81)
ELF_RELOC(R_SPARC_GOTDATA_OP_HIX22, 82)
-ELF_RELOC(R_SPARC_GOTDATA_OP_LOX22, 83)
+ELF_RELOC(R_SPARC_GOTDATA_OP_LOX10, 83)
ELF_RELOC(R_SPARC_GOTDATA_OP, 84)
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 021f904f6ee..4a33f7fc346 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -947,6 +947,8 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
return false;
}
+// Determine if an expression contains a reference to the symbol
+// "_GLOBAL_OFFSET_TABLE_".
static bool hasGOTReference(const MCExpr *Expr) {
switch (Expr->getKind()) {
case MCExpr::Target:
@@ -998,6 +1000,13 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
+ // Ugly: if a sparc assembly expression says "%hi(...)" but the
+ // expression within contains _GLOBAL_OFFSET_TABLE_, it REALLY means
+ // %pc22. Same with %lo -> %pc10. Worse, if it doesn't contain that,
+ // the meaning depends on whether the assembler was invoked with
+ // -KPIC or not: if so, it really means %got22/%got10; if not, it
+ // actually means what it said! Sigh, historical mistakes...
+
switch(VK) {
default: break;
case SparcMCExpr::VK_Sparc_LO:
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index 4f07ae21920..0be60fd7a05 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -31,6 +31,10 @@ namespace {
protected:
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel) const override;
+
+ bool needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const override;
+
};
}
@@ -105,6 +109,27 @@ unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target,
return ELF::R_SPARC_NONE;
}
+bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const {
+ switch (Type) {
+ default:
+ return false;
+
+ // All relocations that use a GOT need a symbol, not an offset, as
+ // the offset of the symbol within the section is irrelevant to
+ // where the GOT entry is. Don't need to list all the TLS entries,
+ // as they're all marked as requiring a symbol anyways.
+ case ELF::R_SPARC_GOT10:
+ case ELF::R_SPARC_GOT13:
+ case ELF::R_SPARC_GOT22:
+ case ELF::R_SPARC_GOTDATA_HIX22:
+ case ELF::R_SPARC_GOTDATA_LOX10:
+ case ELF::R_SPARC_GOTDATA_OP_HIX22:
+ case ELF::R_SPARC_GOTDATA_OP_LOX10:
+ return true;
+ }
+}
+
MCObjectWriter *llvm::createSparcELFObjectWriter(raw_pwrite_stream &OS,
bool Is64Bit,
bool IsLittleEndian,
diff --git a/llvm/test/CodeGen/SPARC/obj-relocs.ll b/llvm/test/CodeGen/SPARC/obj-relocs.ll
index 115263ac5d4..0e7e04032be 100644
--- a/llvm/test/CodeGen/SPARC/obj-relocs.ll
+++ b/llvm/test/CodeGen/SPARC/obj-relocs.ll
@@ -1,31 +1,37 @@
; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=static | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-ABS
; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=pic | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-PIC
-;CHECK-ABS: Relocations [
-;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_H44 AGlobalVar 0x0
-;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_M44 AGlobalVar 0x0
-;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_L44 AGlobalVar 0x0
-;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_WDISP30 bar 0x0
-;CHECK-ABS:]
+;CHECK-ABS: Relocations [
+;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_H44 AGlobalVar 0x0
+;CHECK-ABS-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_M44 AGlobalVar 0x0
+;CHECK-ABS-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_L44 AGlobalVar 0x0
+;CHECK-ABS-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_H44 .rodata.str1.1 0x0
+;CHECK-ABS-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_M44 .rodata.str1.1 0x0
+;CHECK-ABS-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_WDISP30 bar 0x0
+;CHECK-ABS-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_L44 .rodata.str1.1 0x0
+;CHECK-ABS: ]
-; CHECK-PIC: Relocations [
-; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
-; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
-; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
-; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
-; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
-; CHECK-PIC: ]
+; CHECK-PIC: Relocations [
+; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
+; CHECK-PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
+; CHECK-PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
+; CHECK-PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
+; CHECK-PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 .L.mystr 0x0
+; CHECK-PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 .L.mystr 0x0
+; CHECK-PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
+; CHECK-PIC: ]
@AGlobalVar = global i64 0, align 8
+@.mystr = private unnamed_addr constant [6 x i8] c"hello\00", align 1
define i64 @foo(i64 %a) {
entry:
%0 = load i64, i64* @AGlobalVar, align 4
%1 = add i64 %a, %0
- %2 = call i64 @bar(i64 %1)
+ %2 = call i64 @bar(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.mystr, i32 0, i32 0), i64 %1)
ret i64 %2
}
-declare i64 @bar(i64)
+declare i64 @bar(i8*, i64)
diff --git a/llvm/test/MC/Sparc/sparc-pic.s b/llvm/test/MC/Sparc/sparc-pic.s
index 5a34d309899..5430d1fea10 100644
--- a/llvm/test/MC/Sparc/sparc-pic.s
+++ b/llvm/test/MC/Sparc/sparc-pic.s
@@ -7,9 +7,16 @@
! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
+! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 .LC0 0x0
+! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 .LC0 0x0
! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
! CHECK: ]
+ .section ".rodata"
+ .align 8
+.LC0:
+ .asciz "string"
+ .section ".text"
.text
.globl foo
.align 4
@@ -29,8 +36,11 @@ foo:
add %i1, %o7, %i1
sethi %hi(AGlobalVar), %i2
add %i2, %lo(AGlobalVar), %i2
- ldx [%i1+%i2], %i1
- ldx [%i1], %i1
+ ldx [%i1+%i2], %i3
+ ldx [%i3], %i3
+ sethi %hi(.LC0), %i2
+ add %i2, %lo(.LC0), %i2
+ ldx [%i1+%i2], %i4
call bar
add %i0, %i1, %o0
ret
@@ -46,4 +56,3 @@ foo:
AGlobalVar:
.xword 0 ! 0x0
.size AGlobalVar, 8
-
OpenPOWER on IntegriCloud