[llvm-commits] [llvm] r114786 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp lib/MC/MCELFStreamer.cpp lib/Target/X86/X86AsmBackend.cpp test/MC/ELF/basic-elf.ll test/MC/ELF/merge.s
Rafael Espindola
rafael.espindola at gmail.com
Fri Sep 24 22:42:19 PDT 2010
Author: rafael
Date: Sat Sep 25 00:42:19 2010
New Revision: 114786
URL: http://llvm.org/viewvc/llvm-project?rev=114786&view=rev
Log:
Move ELF to HasReliableSymbolDifference=true. Also take the opportunity to put
symbols defined in merge sections in independent atoms.
Added:
llvm/trunk/test/MC/ELF/merge.s
Modified:
llvm/trunk/lib/MC/ELFObjectWriter.cpp
llvm/trunk/lib/MC/MCELFStreamer.cpp
llvm/trunk/lib/Target/X86/X86AsmBackend.cpp
llvm/trunk/test/MC/ELF/basic-elf.ll
Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=114786&r1=114785&r2=114786&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sat Sep 25 00:42:19 2010
@@ -487,6 +487,13 @@
}
}
+static const MCSymbolData *getAtom(const MCSymbolData &SD) {
+ if (!SD.getFragment())
+ return 0;
+
+ return SD.getFragment()->getAtom();
+}
+
// FIXME: this is currently X86/X86_64 only
void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
@@ -502,7 +509,7 @@
if (!Target.isAbsolute()) {
const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
MCSymbolData &SD = Asm.getSymbolData(*Symbol);
- const MCSymbolData *Base = Asm.getAtom(Layout, &SD);
+ const MCSymbolData *Base = getAtom(SD);
MCFragment *F = SD.getFragment();
// Avoid relocations for cases like jumps and calls in the same file.
@@ -515,7 +522,7 @@
}
if (Base) {
- if (F && !SD.isExternal()) {
+ if (Base != &SD) {
Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
MCSectionData *FSD = F->getParent();
@@ -523,8 +530,6 @@
Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
} else
Index = getSymbolIndexInSymbolTable(Asm, Symbol);
- if (Base != &SD)
- Value += Layout.getSymbolAddress(&SD) - Layout.getSymbolAddress(Base);
Addend = Value;
// Compensate for the addend on i386.
if (Is64Bit)
@@ -537,11 +542,14 @@
MCSectionData *FSD = F->getParent();
// Offset of the symbol in the section
- Addend = Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
+ Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
} else {
- FixedValue = Value;
- return;
+ Index = getSymbolIndexInSymbolTable(Asm, Symbol);
}
+ Addend = Value;
+ // Compensate for the addend on i386.
+ if (Is64Bit)
+ Value = 0;
}
}
Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=114786&r1=114785&r2=114786&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Sat Sep 25 00:42:19 2010
@@ -149,20 +149,43 @@
SetSectionText();
}
+static bool isSymbolLinkerVisible(const MCAssembler &Asm,
+ const MCSymbolData &Data) {
+ const MCSymbol &Symbol = Data.getSymbol();
+ // Absolute temporary labels are never visible.
+ if (!Symbol.isInSection())
+ return false;
+
+ if (Asm.getBackend().doesSectionRequireSymbols(Symbol.getSection()))
+ return true;
+
+ if (!Data.isExternal())
+ return false;
+
+ return Asm.isSymbolLinkerVisible(Symbol);
+}
+
void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+ Symbol->setSection(*CurSection);
+
+ MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
+ // We have to create a new fragment if this is an atom defining symbol,
+ // fragments cannot span atoms.
+ if (isSymbolLinkerVisible(getAssembler(), SD))
+ new MCDataFragment(getCurrentSectionData());
+
// FIXME: This is wasteful, we don't necessarily need to create a data
// fragment. Instead, we should mark the symbol as pointing into the data
// fragment if it exists, otherwise we should just queue the label and set its
// fragment pointer when we emit the next fragment.
MCDataFragment *F = getOrCreateDataFragment();
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
SD.setFragment(F);
SD.setOffset(F->getContents().size());
-
- Symbol->setSection(*CurSection);
}
void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
@@ -476,7 +499,37 @@
}
void MCELFStreamer::Finish() {
- getAssembler().Finish();
+ // FIXME: We create more atoms than it is necessary. Some relocations to
+ // merge sections can be implemented with section address + offset,
+ // figure out which ones and why.
+
+ // First, scan the symbol table to build a lookup table from fragments to
+ // defining symbols.
+ DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap;
+ for (MCAssembler::symbol_iterator it = getAssembler().symbol_begin(),
+ ie = getAssembler().symbol_end(); it != ie; ++it) {
+ if (isSymbolLinkerVisible(getAssembler(), *it) &&
+ it->getFragment()) {
+ // An atom defining symbol should never be internal to a fragment.
+ assert(it->getOffset() == 0 && "Invalid offset in atom defining symbol!");
+ DefiningSymbolMap[it->getFragment()] = it;
+ }
+ }
+
+ // Set the fragment atom associations by tracking the last seen atom defining
+ // symbol.
+ for (MCAssembler::iterator it = getAssembler().begin(),
+ ie = getAssembler().end(); it != ie; ++it) {
+ MCSymbolData *CurrentAtom = 0;
+ for (MCSectionData::iterator it2 = it->begin(),
+ ie2 = it->end(); it2 != ie2; ++it2) {
+ if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2))
+ CurrentAtom = SD;
+ it2->setAtom(CurrentAtom);
+ }
+ }
+
+ this->MCObjectStreamer::Finish();
}
MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=114786&r1=114785&r2=114786&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Sat Sep 25 00:42:19 2010
@@ -191,6 +191,12 @@
: X86AsmBackend(T), OSType(_OSType) {
HasAbsolutizedSet = true;
HasScatteredSymbols = true;
+ HasReliableSymbolDifference = true;
+ }
+
+ virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+ const MCSectionELF &ES = static_cast<const MCSectionELF&>(Section);
+ return ES.getFlags() & MCSectionELF::SHF_MERGE;
}
bool isVirtualSection(const MCSection &Section) const {
Modified: llvm/trunk/test/MC/ELF/basic-elf.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/basic-elf.ll?rev=114786&r1=114785&r2=114786&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/basic-elf.ll (original)
+++ llvm/trunk/test/MC/ELF/basic-elf.ll Sat Sep 25 00:42:19 2010
@@ -83,7 +83,7 @@
; 64: # Relocation 2
; 64: (('r_offset', 15)
; 64: ('r_type', 10)
-; 64: ('r_addend', 6)
+; 64: ('r_addend', 0)
; 64: ),
; 64: # Relocation 3
; 64: (('r_offset', 20)
Added: llvm/trunk/test/MC/ELF/merge.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/merge.s?rev=114786&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/merge.s (added)
+++ llvm/trunk/test/MC/ELF/merge.s Sat Sep 25 00:42:19 2010
@@ -0,0 +1,26 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s
+
+// Test that relocations with local symbols in a mergeable section are done
+// with a reference to the symbol. Not sure if this is a linker limitation,
+// but this matches the behavior of gas.
+
+ .section .sec1,"aM", at progbits,16
+.Lfoo:
+ .text
+ movsd .Lfoo(%rip), %xmm1
+
+// Relocation refers to symbol 1
+
+// CHECK: ('_relocations', [
+// CHECK-NEXT: # Relocation 0
+// CHECK-NEXT: (('r_offset',
+// CHECK-NEXT: ('r_sym', 1)
+// CHECK-NEXT: ('r_type',
+// CHECK-NEXT: ('r_addend',
+// CHECK-NEXT: ),
+// CHECK-NEXT: ])
+
+// Symbol number 1 is .Lfoo
+
+// CHECK: # Symbol 1
+// CHECK-NEXT: (('st_name', 1) # '.Lfoo'
More information about the llvm-commits
mailing list