mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-25 03:55:25 +00:00
Add initial support for R_386_GOT32X.
This adds it only for movl mov@GOT(%reg), %reg. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274678 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7bae2669d5
commit
b2ad34a6ea
@ -46,6 +46,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
|
||||
case X86::reloc_riprel_4byte_relax_rex:
|
||||
case X86::reloc_riprel_4byte_movq_load:
|
||||
case X86::reloc_signed_4byte:
|
||||
case X86::reloc_signed_4byte_relax:
|
||||
case X86::reloc_global_offset_table:
|
||||
case FK_SecRel_4:
|
||||
case FK_Data_4:
|
||||
@ -93,6 +94,7 @@ public:
|
||||
{"reloc_riprel_4byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
|
||||
{"reloc_riprel_4byte_relax_rex", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
|
||||
{"reloc_signed_4byte", 0, 32, 0},
|
||||
{"reloc_signed_4byte_relax", 0, 32, 0},
|
||||
{"reloc_global_offset_table", 0, 32, 0},
|
||||
{"reloc_global_offset_table8", 0, 64, 0},
|
||||
};
|
||||
|
@ -58,6 +58,7 @@ static X86_64RelType getType64(unsigned Kind,
|
||||
case FK_Data_8:
|
||||
return RT64_64;
|
||||
case X86::reloc_signed_4byte:
|
||||
case X86::reloc_signed_4byte_relax:
|
||||
if (Modifier == MCSymbolRefExpr::VK_None && !IsPCRel)
|
||||
return RT64_32S;
|
||||
return RT64_32;
|
||||
@ -210,8 +211,10 @@ static X86_32RelType getType32(X86_64RelType T) {
|
||||
llvm_unreachable("unexpected relocation type!");
|
||||
}
|
||||
|
||||
static unsigned getRelocType32(MCSymbolRefExpr::VariantKind Modifier,
|
||||
X86_32RelType Type, bool IsPCRel) {
|
||||
static unsigned getRelocType32(MCContext &Ctx,
|
||||
MCSymbolRefExpr::VariantKind Modifier,
|
||||
X86_32RelType Type, bool IsPCRel,
|
||||
unsigned Kind) {
|
||||
switch (Modifier) {
|
||||
default:
|
||||
llvm_unreachable("Unimplemented");
|
||||
@ -226,7 +229,15 @@ static unsigned getRelocType32(MCSymbolRefExpr::VariantKind Modifier,
|
||||
}
|
||||
case MCSymbolRefExpr::VK_GOT:
|
||||
assert(Type == RT32_32);
|
||||
return IsPCRel ? ELF::R_386_GOTPC : ELF::R_386_GOT32;
|
||||
if (IsPCRel)
|
||||
return ELF::R_386_GOTPC;
|
||||
// Older versions of ld.bfd/ld.gold/lld do not support R_386_GOT32X and we
|
||||
// want to maintain compatibility.
|
||||
if (!Ctx.getAsmInfo()->canRelaxRelocations())
|
||||
return ELF::R_386_GOT32;
|
||||
|
||||
return Kind == X86::reloc_signed_4byte_relax ? ELF::R_386_GOT32X
|
||||
: ELF::R_386_GOT32;
|
||||
case MCSymbolRefExpr::VK_GOTOFF:
|
||||
assert(Type == RT32_32);
|
||||
assert(!IsPCRel);
|
||||
@ -273,14 +284,14 @@ unsigned X86ELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
|
||||
const MCFixup &Fixup,
|
||||
bool IsPCRel) const {
|
||||
MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
|
||||
X86_64RelType Type = getType64(Fixup.getKind(), Modifier, IsPCRel);
|
||||
unsigned Kind = Fixup.getKind();
|
||||
X86_64RelType Type = getType64(Kind, Modifier, IsPCRel);
|
||||
if (getEMachine() == ELF::EM_X86_64)
|
||||
return getRelocType64(Ctx, Fixup.getLoc(), Modifier, Type, IsPCRel,
|
||||
Fixup.getKind());
|
||||
return getRelocType64(Ctx, Fixup.getLoc(), Modifier, Type, IsPCRel, Kind);
|
||||
|
||||
assert((getEMachine() == ELF::EM_386 || getEMachine() == ELF::EM_IAMCU) &&
|
||||
"Unsupported ELF machine type.");
|
||||
return getRelocType32(Modifier, getType32(Type), IsPCRel);
|
||||
return getRelocType32(Ctx, Modifier, getType32(Type), IsPCRel, Kind);
|
||||
}
|
||||
|
||||
MCObjectWriter *llvm::createX86ELFObjectWriter(raw_pwrite_stream &OS,
|
||||
|
@ -24,6 +24,8 @@ enum Fixups {
|
||||
reloc_signed_4byte, // 32-bit signed. Unlike FK_Data_4
|
||||
// this will be sign extended at
|
||||
// runtime.
|
||||
reloc_signed_4byte_relax, // like reloc_signed_4byte, but
|
||||
// in a relaxable instruction.
|
||||
reloc_global_offset_table, // 32-bit, relative to the start
|
||||
// of the instruction. Used only
|
||||
// for _GLOBAL_OFFSET_TABLE_.
|
||||
|
@ -516,8 +516,11 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
|
||||
// Otherwise, emit the most general non-SIB encoding: [REG+disp32]
|
||||
EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS);
|
||||
EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
|
||||
CurByte, OS, Fixups);
|
||||
unsigned Opcode = MI.getOpcode();
|
||||
unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax
|
||||
: X86::reloc_signed_4byte;
|
||||
EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), CurByte, OS,
|
||||
Fixups);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
|
||||
case X86::reloc_riprel_4byte_relax_rex:
|
||||
case X86::reloc_riprel_4byte_movq_load:
|
||||
case X86::reloc_signed_4byte:
|
||||
case X86::reloc_signed_4byte_relax:
|
||||
case FK_Data_4: return 2;
|
||||
case FK_Data_8: return 3;
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
|
||||
return COFF::IMAGE_REL_I386_REL32;
|
||||
case FK_Data_4:
|
||||
case X86::reloc_signed_4byte:
|
||||
case X86::reloc_signed_4byte_relax:
|
||||
if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
|
||||
return COFF::IMAGE_REL_I386_DIR32NB;
|
||||
if (Modifier == MCSymbolRefExpr::VK_SECREL)
|
||||
|
22
test/MC/ELF/got-relaxed-i386.s
Normal file
22
test/MC/ELF/got-relaxed-i386.s
Normal file
@ -0,0 +1,22 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple i386-pc-linux %s -o - | llvm-readobj -r | FileCheck %s
|
||||
// RUN: llvm-mc -filetype=obj -relax-relocations=false -triple i386-pc-linux %s -o - | llvm-readobj -r | FileCheck --check-prefix=OLD %s
|
||||
|
||||
movl mov@GOT(%ebx), %eax
|
||||
mull mul@GOT(%ebx)
|
||||
.long long@GOT
|
||||
|
||||
// CHECK: Relocations [
|
||||
// CHECK-NEXT: Section ({{.*}}) .rel.text {
|
||||
// CHECK-NEXT: R_386_GOT32X mov
|
||||
// CHECK-NEXT: R_386_GOT32 mul
|
||||
// CHECK-NEXT: R_386_GOT32 long
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
// OLD: Relocations [
|
||||
// OLD-NEXT: Section ({{.*}}) .rel.text {
|
||||
// OLD-NEXT: R_386_GOT32 mov
|
||||
// OLD-NEXT: R_386_GOT32 mul
|
||||
// OLD-NEXT: R_386_GOT32 long
|
||||
// OLD-NEXT: }
|
||||
// OLD-NEXT: ]
|
@ -1,5 +1,5 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - | llvm-readobj -r | FileCheck %s --check-prefix=CHECK --check-prefix=I386
|
||||
// RUN: llvm-mc -filetype=obj -triple i386-pc-elfiamcu %s -o - | llvm-readobj -r | FileCheck %s --check-prefix=CHECK --check-prefix=IAMCU
|
||||
// RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -relax-relocations=false -o - | llvm-readobj -r | FileCheck %s --check-prefix=CHECK --check-prefix=I386
|
||||
// RUN: llvm-mc -filetype=obj -triple i386-pc-elfiamcu %s -relax-relocations=false -o - | llvm-readobj -r | FileCheck %s --check-prefix=CHECK --check-prefix=IAMCU
|
||||
|
||||
// Test that we produce the correct relocation types and that the relocations
|
||||
// correctly point to the section or the symbol.
|
||||
|
Loading…
x
Reference in New Issue
Block a user