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) { static bool ShouldRelocOnSymbol(const MCSymbolData &SD,
if (!SD.getFragment()) const MCValue &Target) {
return 0; 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 // FIXME: this is currently X86/X86_64 only
@ -522,20 +533,19 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
if (!Target.isAbsolute()) { if (!Target.isAbsolute()) {
const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
MCSymbolData &SD = Asm.getSymbolData(*Symbol); MCSymbolData &SD = Asm.getSymbolData(*Symbol);
const MCSymbolData *Base = getAtom(SD);
MCFragment *F = SD.getFragment(); 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() && if (Symbol->isDefined() && !SD.isExternal() &&
IsPCRel && IsPCRel &&
&Fragment->getParent()->getSection() == &Symbol->getSection()) { &Fragment->getParent()->getSection() == &Symbol->getSection()) {
uint64_t FixupAddr = Layout.getFragmentAddress(Fragment) + Fixup.getOffset(); llvm_unreachable("We don't need a relocation in this case.");
FixedValue = Layout.getSymbolAddress(&SD) + Target.getConstant() - FixupAddr;
return; return;
} }
if (Base) { bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target);
if (Base != &SD) { if (!RelocOnSymbol) {
Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1; Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
MCSectionData *FSD = F->getParent(); MCSectionData *FSD = F->getParent();
@ -547,23 +557,6 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
// Compensate for the addend on i386. // Compensate for the addend on i386.
if (Is64Bit) if (Is64Bit)
Value = 0; 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;
}
} }
FixedValue = Value; FixedValue = Value;

View File

@ -101,7 +101,7 @@ declare i32 @puts(i8* nocapture) nounwind
; 64: # Relocation 2 ; 64: # Relocation 2
; 64: (('r_offset', 15) ; 64: (('r_offset', 15)
; 64: ('r_type', 10) ; 64: ('r_type', 10)
; 64: ('r_addend', 0) ; 64: ('r_addend', 6)
; 64: ), ; 64: ),
; 64: # Relocation 3 ; 64: # Relocation 3
; 64: (('r_offset', 20) ; 64: (('r_offset', 20)

View File

@ -10,39 +10,48 @@ bar:
movq bar, %rdx // R_X86_64_32S movq bar, %rdx // R_X86_64_32S
.long bar // R_X86_64_32 .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: # Relocation 0
// CHECK-NEXT: (('r_offset', 1) // CHECK-NEXT: (('r_offset', 1)
// CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_sym', 2)
// CHECK-NEXT: ('r_type', 10) // CHECK-NEXT: ('r_type', 10)
// CHECK-NEXT: ('r_addend', // CHECK-NEXT: ('r_addend',
// CHECK: # Relocation 1 // CHECK: # Relocation 1
// CHECK-NEXT: (('r_offset', 8) // CHECK-NEXT: (('r_offset', 8)
// CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_sym', 2)
// CHECK-NEXT: ('r_type', 11) // CHECK-NEXT: ('r_type', 11)
// CHECK-NEXT: ('r_addend', // CHECK-NEXT: ('r_addend',
// CHECK: # Relocation 2 // CHECK: # Relocation 2
// CHECK-NEXT: (('r_offset', 19) // CHECK-NEXT: (('r_offset', 19)
// CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_sym', 2)
// CHECK-NEXT: ('r_type', 11) // CHECK-NEXT: ('r_type', 11)
// CHECK-NEXT: ('r_addend', // CHECK-NEXT: ('r_addend',
// CHECK: # Relocation 3 // CHECK: # Relocation 3
// CHECK-NEXT: (('r_offset', 26) // CHECK-NEXT: (('r_offset', 26)
// CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_sym', 2)
// CHECK-NEXT: ('r_type', 11) // CHECK-NEXT: ('r_type', 11)
// CHECK-NEXT: ('r_addend', // CHECK-NEXT: ('r_addend',
// CHECK: # Relocation 4 // CHECK: # Relocation 4
// CHECK-NEXT: (('r_offset', 34) // CHECK-NEXT: (('r_offset', 34)
// CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_sym', 2)
// CHECK-NEXT: ('r_type', 11) // CHECK-NEXT: ('r_type', 11)
// CHECK-NEXT: ('r_addend', // CHECK-NEXT: ('r_addend',
// CHECK: # Relocation 5 // CHECK: # Relocation 5
// CHECK-NEXT: (('r_offset', 38) // CHECK-NEXT: (('r_offset', 38)
// CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_sym', 2)
// CHECK-NEXT: ('r_type', 10) // CHECK-NEXT: ('r_type', 10)
// CHECK-NEXT: ('r_addend', // CHECK-NEXT: ('r_addend',