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:
Rafael Espindola 2010-09-30 20:18:35 +00:00
parent a3fbadfcd8
commit 7eae36b38b
3 changed files with 46 additions and 44 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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',