mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-14 07:31:47 +00:00
Fix relocation used for GOT references in non-PIC mode. Fix relocations
for "set" pseudo op in PIC mode. Differential Revision: http://reviews.llvm.org/D13173 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249086 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
52c0444e5e
commit
fd813994db
@ -69,6 +69,10 @@ class SparcAsmParser : public MCTargetAsmParser {
|
||||
|
||||
OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
|
||||
|
||||
// Helper function for dealing with %lo / %hi in PIC mode.
|
||||
const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
|
||||
const MCExpr *subExpr);
|
||||
|
||||
// returns true if Tok is matched to a register and returns register in RegNo.
|
||||
bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
|
||||
unsigned &RegKind);
|
||||
@ -466,8 +470,7 @@ void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
|
||||
// In either case, start with the 'sethi'.
|
||||
if (!IsEffectivelyImm13) {
|
||||
MCInst TmpInst;
|
||||
const MCExpr *Expr =
|
||||
SparcMCExpr::create(SparcMCExpr::VK_Sparc_HI, ValExpr, getContext());
|
||||
const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
|
||||
TmpInst.setLoc(IDLoc);
|
||||
TmpInst.setOpcode(SP::SETHIi);
|
||||
TmpInst.addOperand(MCRegOp);
|
||||
@ -492,8 +495,7 @@ void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
|
||||
if (IsEffectivelyImm13)
|
||||
Expr = ValExpr;
|
||||
else
|
||||
Expr =
|
||||
SparcMCExpr::create(SparcMCExpr::VK_Sparc_LO, ValExpr, getContext());
|
||||
Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
|
||||
TmpInst.setLoc(IDLoc);
|
||||
TmpInst.setOpcode(SP::ORri);
|
||||
TmpInst.addOperand(MCRegOp);
|
||||
@ -1054,6 +1056,32 @@ static bool hasGOTReference(const MCExpr *Expr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const SparcMCExpr *
|
||||
SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
|
||||
const MCExpr *subExpr)
|
||||
{
|
||||
// When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
|
||||
// If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
|
||||
// actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
|
||||
// as %got10 or %got22 relocation.
|
||||
|
||||
if (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) {
|
||||
switch(VK) {
|
||||
default: break;
|
||||
case SparcMCExpr::VK_Sparc_LO:
|
||||
VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10
|
||||
: SparcMCExpr::VK_Sparc_GOT10);
|
||||
break;
|
||||
case SparcMCExpr::VK_Sparc_HI:
|
||||
VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22
|
||||
: SparcMCExpr::VK_Sparc_GOT22);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return SparcMCExpr::create(VK, subExpr, getContext());
|
||||
}
|
||||
|
||||
bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
|
||||
SMLoc &EndLoc)
|
||||
{
|
||||
@ -1077,30 +1105,7 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
|
||||
if (Parser.parseParenExpression(subExpr, EndLoc))
|
||||
return false;
|
||||
|
||||
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:
|
||||
VK = (hasGOTReference(subExpr)
|
||||
? SparcMCExpr::VK_Sparc_PC10
|
||||
: (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK));
|
||||
break;
|
||||
case SparcMCExpr::VK_Sparc_HI:
|
||||
VK = (hasGOTReference(subExpr)
|
||||
? SparcMCExpr::VK_Sparc_PC22
|
||||
: (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK));
|
||||
break;
|
||||
}
|
||||
|
||||
EVal = SparcMCExpr::create(VK, subExpr, getContext());
|
||||
EVal = adjustPICRelocation(VK, subExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,36 @@
|
||||
! RUN: llvm-mc %s -arch=sparcv9 --relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s
|
||||
! RUN: llvm-mc %s -arch=sparcv9 --relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck --check-prefix=PIC %s
|
||||
! RUN: llvm-mc %s -arch=sparcv9 --relocation-model=static -filetype=obj | llvm-readobj -r | FileCheck --check-prefix=NOPIC %s
|
||||
|
||||
|
||||
! CHECK: Relocations [
|
||||
! CHECK-NOT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 .text 0xC
|
||||
! CHECK: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
|
||||
! 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: ]
|
||||
! PIC: Relocations [
|
||||
! PIC-NOT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 .text 0xC
|
||||
! PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x0
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x0
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 .LC0 0x0
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 .LC0 0x0
|
||||
! PIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
|
||||
! PIC: ]
|
||||
|
||||
! NOPIC: Relocations [
|
||||
! NOPIC-NOT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 .text 0xC
|
||||
! NOPIC: 0x{{[0-9,A-F]+}} R_SPARC_HI22 _GLOBAL_OFFSET_TABLE_ 0x4
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_LO10 _GLOBAL_OFFSET_TABLE_ 0x8
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_HI22 _GLOBAL_OFFSET_TABLE_ 0x0
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_LO10 _GLOBAL_OFFSET_TABLE_ 0x0
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_HI22 AGlobalVar 0x0
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_LO10 AGlobalVar 0x0
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_HI22 AGlobalVar 0x0
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_LO10 AGlobalVar 0x0
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_HI22 .rodata 0x0
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_LO10 .rodata 0x0
|
||||
! NOPIC-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_WDISP30 bar 0x0
|
||||
! NOPIC: ]
|
||||
|
||||
.section ".rodata"
|
||||
.align 8
|
||||
@ -33,9 +53,11 @@ foo:
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_+(.Ltmp6-.Ltmp4)), %i1
|
||||
.Ltmp5:
|
||||
or %i1, %lo(_GLOBAL_OFFSET_TABLE_+(.Ltmp5-.Ltmp4)), %i1
|
||||
set _GLOBAL_OFFSET_TABLE_, %i1
|
||||
add %i1, %o7, %i1
|
||||
sethi %hi(AGlobalVar), %i2
|
||||
add %i2, %lo(AGlobalVar), %i2
|
||||
set AGlobalVar, %i2
|
||||
ldx [%i1+%i2], %i3
|
||||
ldx [%i3], %i3
|
||||
sethi %hi(.LC0), %i2
|
||||
|
Loading…
Reference in New Issue
Block a user