mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-29 10:32:47 +00:00
Fix COFF x86-64 relocations. PR7960.
Multiple symbol reloc handling part of the patch by Cameron Esfahani. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111963 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3e242f86eb
commit
82c84fdd23
@ -125,6 +125,7 @@ public:
|
||||
typedef DenseMap<MCSectionData const *, COFFSection *> section_map;
|
||||
|
||||
// Root level file contents.
|
||||
bool Is64Bit;
|
||||
COFF::header Header;
|
||||
sections Sections;
|
||||
symbols Symbols;
|
||||
@ -274,10 +275,11 @@ size_t StringTable::insert(llvm::StringRef String) {
|
||||
// WinCOFFObjectWriter class implementation
|
||||
|
||||
WinCOFFObjectWriter::WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit)
|
||||
: MCObjectWriter(OS, true) {
|
||||
: MCObjectWriter(OS, true)
|
||||
, Is64Bit(is64Bit) {
|
||||
memset(&Header, 0, sizeof(Header));
|
||||
|
||||
is64Bit ? Header.Machine = COFF::IMAGE_FILE_MACHINE_AMD64
|
||||
Is64Bit ? Header.Machine = COFF::IMAGE_FILE_MACHINE_AMD64
|
||||
: Header.Machine = COFF::IMAGE_FILE_MACHINE_I386;
|
||||
}
|
||||
|
||||
@ -565,22 +567,34 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
|
||||
MCValue Target,
|
||||
uint64_t &FixedValue) {
|
||||
assert(Target.getSymA() != NULL && "Relocation must reference a symbol!");
|
||||
assert(Target.getSymB() == NULL &&
|
||||
"Relocation must reference only one symbol!");
|
||||
|
||||
const MCSymbol *A = &Target.getSymA()->getSymbol();
|
||||
MCSymbolData &A_SD = Asm.getSymbolData(*A);
|
||||
|
||||
MCSectionData const *SectionData = Fragment->getParent();
|
||||
MCSymbolData const *SymbolData =
|
||||
&Asm.getSymbolData(Target.getSymA()->getSymbol());
|
||||
|
||||
// Mark this symbol as requiring an entry in the symbol table.
|
||||
assert(SectionMap.find(SectionData) != SectionMap.end() &&
|
||||
"Section must already have been defined in ExecutePostLayoutBinding!");
|
||||
assert(SymbolMap.find(SymbolData) != SymbolMap.end() &&
|
||||
assert(SymbolMap.find(&A_SD) != SymbolMap.end() &&
|
||||
"Symbol must already have been defined in ExecutePostLayoutBinding!");
|
||||
|
||||
COFFSection *coff_section = SectionMap[SectionData];
|
||||
COFFSymbol *coff_symbol = SymbolMap[SymbolData];
|
||||
COFFSymbol *coff_symbol = SymbolMap[&A_SD];
|
||||
|
||||
FixedValue = Target.getConstant();
|
||||
if (Target.getSymB()) {
|
||||
const MCSymbol *B = &Target.getSymB()->getSymbol();
|
||||
MCSymbolData &B_SD = Asm.getSymbolData(*B);
|
||||
|
||||
FixedValue = Layout.getSymbolAddress(&A_SD) - Layout.getSymbolAddress(&B_SD);
|
||||
|
||||
// In the case where we have SymbA and SymB, we just need to store the delta
|
||||
// between the two symbols. Update FixedValue to account for the delta, and
|
||||
// skip recording the relocation.
|
||||
return;
|
||||
} else {
|
||||
FixedValue = Target.getConstant();
|
||||
}
|
||||
|
||||
COFFRelocation Reloc;
|
||||
|
||||
@ -590,40 +604,29 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
|
||||
|
||||
Reloc.Data.VirtualAddress += Fixup.getOffset();
|
||||
|
||||
COFF::RelocationTypeX86 Type;
|
||||
|
||||
if (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386) {
|
||||
switch (Fixup.getKind()) {
|
||||
case X86::reloc_pcrel_4byte:
|
||||
Type = COFF::IMAGE_REL_I386_REL32;
|
||||
FixedValue += 4;
|
||||
break;
|
||||
case FK_Data_4:
|
||||
Type = COFF::IMAGE_REL_I386_DIR32;
|
||||
break;
|
||||
default:
|
||||
switch (Fixup.getKind()) {
|
||||
case X86::reloc_pcrel_4byte:
|
||||
case X86::reloc_riprel_4byte:
|
||||
case X86::reloc_riprel_4byte_movq_load:
|
||||
Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_REL32
|
||||
: COFF::IMAGE_REL_I386_REL32;
|
||||
// FIXME: Can anyone explain what this does other than adjust for the size
|
||||
// of the offset?
|
||||
FixedValue += 4;
|
||||
break;
|
||||
case FK_Data_4:
|
||||
Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32
|
||||
: COFF::IMAGE_REL_I386_DIR32;
|
||||
break;
|
||||
case FK_Data_8:
|
||||
if (Is64Bit)
|
||||
Reloc.Data.Type = COFF::IMAGE_REL_AMD64_ADDR64;
|
||||
else
|
||||
llvm_unreachable("unsupported relocation type");
|
||||
}
|
||||
} else if (Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64) {
|
||||
switch (Fixup.getKind()) {
|
||||
case FK_Data_8:
|
||||
Type = COFF::IMAGE_REL_AMD64_ADDR64;
|
||||
break;
|
||||
case X86::reloc_pcrel_4byte:
|
||||
case X86::reloc_riprel_4byte:
|
||||
Type = COFF::IMAGE_REL_AMD64_REL32;
|
||||
FixedValue += 4;
|
||||
break;
|
||||
case FK_Data_4:
|
||||
Type = COFF::IMAGE_REL_AMD64_ADDR32;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unsupported relocation type");
|
||||
}
|
||||
} else
|
||||
llvm_unreachable("unknown target architecture");
|
||||
|
||||
Reloc.Data.Type = Type;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unsupported relocation type");
|
||||
}
|
||||
|
||||
coff_section->Relocations.push_back(Reloc);
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
; RUN: llc -filetype=obj %s -o %t
|
||||
; RUN: coff-dump.py %abs_tmp | FileCheck %s
|
||||
; This test checks that the COFF object emitter works for the most basic
|
||||
; programs.
|
||||
|
||||
; ModuleID = '-'
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
|
||||
target triple = "i686-pc-win32"
|
||||
; RUN: llc -filetype=obj -mtriple i686-pc-win32 %s -o %t
|
||||
; RUN: coff-dump.py %abs_tmp | FileCheck %s
|
||||
; RUN: llc -filetype=obj -mtriple x86_64-pc-win32 %s -o %t
|
||||
|
||||
@.str = private constant [12 x i8] c"Hello World\00" ; <[12 x i8]*> [#uses=1]
|
||||
|
||||
|
34
test/MC/COFF/switch-relocations.ll
Normal file
34
test/MC/COFF/switch-relocations.ll
Normal file
@ -0,0 +1,34 @@
|
||||
; The purpose of this test is to see if the COFF object writer can properly
|
||||
; relax the fixups that are created for jump tables on x86-64. See PR7960.
|
||||
|
||||
; This test case was reduced from Lua/lapi.c.
|
||||
|
||||
; RUN: llc -filetype=obj -mtriple i686-pc-win32 %s -o %t
|
||||
; RUN: llc -filetype=obj -mtriple x86_64-pc-win32 %s -o %t
|
||||
|
||||
define void @lua_gc(i32 %what) nounwind {
|
||||
entry:
|
||||
switch i32 %what, label %sw.epilog [
|
||||
i32 0, label %sw.bb
|
||||
i32 1, label %sw.bb
|
||||
i32 2, label %sw.bb
|
||||
i32 3, label %sw.bb14
|
||||
i32 4, label %sw.bb18
|
||||
i32 6, label %sw.bb57
|
||||
]
|
||||
|
||||
sw.bb: ; preds = %entry, %entry, %entry
|
||||
ret void
|
||||
|
||||
sw.bb14: ; preds = %entry
|
||||
ret void
|
||||
|
||||
sw.bb18: ; preds = %entry
|
||||
ret void
|
||||
|
||||
sw.bb57: ; preds = %entry
|
||||
ret void
|
||||
|
||||
sw.epilog: ; preds = %entry
|
||||
ret void
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
; RUN: llc -filetype=obj %s -o %t
|
||||
; RUN: coff-dump.py %abs_tmp | FileCheck %s
|
||||
; The purpose of this test is to see if the COFF object writer is emitting the
|
||||
; proper relocations for multiple pieces of data in a single data fragment.
|
||||
|
||||
; ModuleID = 'coff-fragment-test.c'
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
|
||||
target triple = "i686-pc-win32"
|
||||
; RUN: llc -filetype=obj -mtriple i686-pc-win32 %s -o %t
|
||||
; RUN: coff-dump.py %abs_tmp | FileCheck %s
|
||||
; RUN: llc -filetype=obj -mtriple x86_64-pc-win32 %s -o %t
|
||||
|
||||
@.str = private constant [7 x i8] c"Hello \00" ; <[7 x i8]*> [#uses=1]
|
||||
@str = internal constant [7 x i8] c"World!\00" ; <[7 x i8]*> [#uses=1]
|
||||
|
Loading…
Reference in New Issue
Block a user