mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Factor some logic into ShouldRelocOnSymbol. This simplifies the code and
fixes some cases where we were producing relocations with at symbol that should use a section instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115194 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a3fbadfcd8
commit
7eae36b38b
@ -500,11 +500,22 @@ void ELFObjectWriterImpl::WriteSymbolTable(MCDataFragment *F,
|
||||
}
|
||||
}
|
||||
|
||||
static const MCSymbolData *getAtom(const MCSymbolData &SD) {
|
||||
if (!SD.getFragment())
|
||||
return 0;
|
||||
static bool ShouldRelocOnSymbol(const MCSymbolData &SD,
|
||||
const MCValue &Target) {
|
||||
const MCSymbol &Symbol = SD.getSymbol();
|
||||
if (Symbol.isUndefined())
|
||||
return true;
|
||||
|
||||
return SD.getFragment()->getAtom();
|
||||
const MCSectionELF &Section =
|
||||
static_cast<const MCSectionELF&>(Symbol.getSection());
|
||||
|
||||
if (Section.getFlags() & MCSectionELF::SHF_MERGE)
|
||||
return Target.getConstant() != 0;
|
||||
|
||||
if (SD.isExternal())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: this is currently X86/X86_64 only
|
||||
@ -522,48 +533,30 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
|
||||
if (!Target.isAbsolute()) {
|
||||
const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
|
||||
MCSymbolData &SD = Asm.getSymbolData(*Symbol);
|
||||
const MCSymbolData *Base = getAtom(SD);
|
||||
MCFragment *F = SD.getFragment();
|
||||
|
||||
// Avoid relocations for cases like jumps and calls in the same file.
|
||||
// Check that this case has already been fully resolved before we get
|
||||
// here.
|
||||
if (Symbol->isDefined() && !SD.isExternal() &&
|
||||
IsPCRel &&
|
||||
&Fragment->getParent()->getSection() == &Symbol->getSection()) {
|
||||
uint64_t FixupAddr = Layout.getFragmentAddress(Fragment) + Fixup.getOffset();
|
||||
FixedValue = Layout.getSymbolAddress(&SD) + Target.getConstant() - FixupAddr;
|
||||
llvm_unreachable("We don't need a relocation in this case.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Base) {
|
||||
if (Base != &SD) {
|
||||
Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
|
||||
bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target);
|
||||
if (!RelocOnSymbol) {
|
||||
Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
|
||||
|
||||
MCSectionData *FSD = F->getParent();
|
||||
// Offset of the symbol in the section
|
||||
Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
|
||||
} else
|
||||
Index = getSymbolIndexInSymbolTable(Asm, Symbol);
|
||||
Addend = Value;
|
||||
// Compensate for the addend on i386.
|
||||
if (Is64Bit)
|
||||
Value = 0;
|
||||
} else {
|
||||
if (F) {
|
||||
// Index of the section in .symtab against this symbol
|
||||
// is being relocated + 2 (empty section + abs. symbols).
|
||||
Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
|
||||
|
||||
MCSectionData *FSD = F->getParent();
|
||||
// Offset of the symbol in the section
|
||||
Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
|
||||
} else {
|
||||
Index = getSymbolIndexInSymbolTable(Asm, Symbol);
|
||||
}
|
||||
Addend = Value;
|
||||
// Compensate for the addend on i386.
|
||||
if (Is64Bit)
|
||||
Value = 0;
|
||||
}
|
||||
MCSectionData *FSD = F->getParent();
|
||||
// Offset of the symbol in the section
|
||||
Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
|
||||
} else
|
||||
Index = getSymbolIndexInSymbolTable(Asm, Symbol);
|
||||
Addend = Value;
|
||||
// Compensate for the addend on i386.
|
||||
if (Is64Bit)
|
||||
Value = 0;
|
||||
}
|
||||
|
||||
FixedValue = Value;
|
||||
|
@ -101,7 +101,7 @@ declare i32 @puts(i8* nocapture) nounwind
|
||||
; 64: # Relocation 2
|
||||
; 64: (('r_offset', 15)
|
||||
; 64: ('r_type', 10)
|
||||
; 64: ('r_addend', 0)
|
||||
; 64: ('r_addend', 6)
|
||||
; 64: ),
|
||||
; 64: # Relocation 3
|
||||
; 64: (('r_offset', 20)
|
||||
|
@ -10,39 +10,48 @@ bar:
|
||||
movq bar, %rdx // R_X86_64_32S
|
||||
.long bar // R_X86_64_32
|
||||
|
||||
// CHECK: # Section 1
|
||||
// CHECK: (('sh_name', 1) # '.text'
|
||||
|
||||
// CHECK: # Symbol 2
|
||||
// CHECK: (('st_name', 0) # ''
|
||||
// CHECK: ('st_bind', 0)
|
||||
// CHECK ('st_type', 3)
|
||||
// CHECK: ('st_other', 0)
|
||||
// CHECK: ('st_shndx', 1)
|
||||
|
||||
// CHECK: # Relocation 0
|
||||
// CHECK-NEXT: (('r_offset', 1)
|
||||
// CHECK-NEXT: ('r_sym',
|
||||
// CHECK-NEXT: ('r_sym', 2)
|
||||
// CHECK-NEXT: ('r_type', 10)
|
||||
// CHECK-NEXT: ('r_addend',
|
||||
|
||||
// CHECK: # Relocation 1
|
||||
// CHECK-NEXT: (('r_offset', 8)
|
||||
// CHECK-NEXT: ('r_sym',
|
||||
// CHECK-NEXT: ('r_sym', 2)
|
||||
// CHECK-NEXT: ('r_type', 11)
|
||||
// CHECK-NEXT: ('r_addend',
|
||||
|
||||
// CHECK: # Relocation 2
|
||||
// CHECK-NEXT: (('r_offset', 19)
|
||||
// CHECK-NEXT: ('r_sym',
|
||||
// CHECK-NEXT: ('r_sym', 2)
|
||||
// CHECK-NEXT: ('r_type', 11)
|
||||
// CHECK-NEXT: ('r_addend',
|
||||
|
||||
// CHECK: # Relocation 3
|
||||
// CHECK-NEXT: (('r_offset', 26)
|
||||
// CHECK-NEXT: ('r_sym',
|
||||
// CHECK-NEXT: ('r_sym', 2)
|
||||
// CHECK-NEXT: ('r_type', 11)
|
||||
// CHECK-NEXT: ('r_addend',
|
||||
|
||||
// CHECK: # Relocation 4
|
||||
// CHECK-NEXT: (('r_offset', 34)
|
||||
// CHECK-NEXT: ('r_sym',
|
||||
// CHECK-NEXT: ('r_sym', 2)
|
||||
// CHECK-NEXT: ('r_type', 11)
|
||||
// CHECK-NEXT: ('r_addend',
|
||||
|
||||
// CHECK: # Relocation 5
|
||||
// CHECK-NEXT: (('r_offset', 38)
|
||||
// CHECK-NEXT: ('r_sym',
|
||||
// CHECK-NEXT: ('r_sym', 2)
|
||||
// CHECK-NEXT: ('r_type', 10)
|
||||
// CHECK-NEXT: ('r_addend',
|
||||
|
Loading…
Reference in New Issue
Block a user