aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/ELFObjectWriter.h2
-rw-r--r--include/llvm/MC/MCObjectWriter.h2
-rw-r--r--include/llvm/MC/MachObjectWriter.h2
-rw-r--r--lib/MC/ELFObjectWriter.cpp67
-rw-r--r--lib/MC/MCELFStreamer.cpp51
-rw-r--r--lib/MC/MachObjectWriter.cpp2
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp4
7 files changed, 50 insertions, 80 deletions
diff --git a/include/llvm/MC/ELFObjectWriter.h b/include/llvm/MC/ELFObjectWriter.h
index c8a42fe57b..aba8b49232 100644
--- a/include/llvm/MC/ELFObjectWriter.h
+++ b/include/llvm/MC/ELFObjectWriter.h
@@ -44,7 +44,7 @@ public:
bool IsPCRel,
const MCFragment *DF) const;
- virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
+ virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 7571583e99..6814cb537b 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -90,7 +90,7 @@ public:
/// This routine is called by the assembler after layout and relaxation is
/// complete, fixups have been evaluated and applied, and relocations
/// generated.
- virtual void WriteObject(const MCAssembler &Asm,
+ virtual void WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) = 0;
/// @}
diff --git a/include/llvm/MC/MachObjectWriter.h b/include/llvm/MC/MachObjectWriter.h
index 198da8fc17..f1079e3d7c 100644
--- a/include/llvm/MC/MachObjectWriter.h
+++ b/include/llvm/MC/MachObjectWriter.h
@@ -41,7 +41,7 @@ public:
bool IsPCRel,
const MCFragment *DF) const;
- virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
+ virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
};
} // End llvm namespace
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 6a2a6e53da..b9d2acea46 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/ELFObjectWriter.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
@@ -102,7 +103,9 @@ namespace {
struct ELFRelocationEntry {
// Make these big enough for both 32-bit and 64-bit
uint64_t r_offset;
- uint64_t r_info;
+ int Index;
+ unsigned Type;
+ const MCSymbol *Symbol;
uint64_t r_addend;
// Support lexicographic sorting.
@@ -111,6 +114,8 @@ namespace {
}
};
+ SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
+
llvm::DenseMap<const MCSectionData*,
std::vector<ELFRelocationEntry> > Relocations;
DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
@@ -126,6 +131,8 @@ namespace {
/// @}
+ int NumRegularSections;
+
ELFObjectWriter *Writer;
raw_ostream &OS;
@@ -262,8 +269,6 @@ namespace {
void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout);
void ExecutePostLayoutBinding(MCAssembler &Asm) {
- // Compute symbol table information.
- ComputeSymbolTable(Asm);
}
void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
@@ -279,7 +284,7 @@ namespace {
bool IsPCRel,
const MCFragment *DF) const;
- void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
};
}
@@ -526,12 +531,13 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
MCValue Target,
uint64_t &FixedValue) {
int64_t Addend = 0;
- unsigned Index = 0;
+ int Index = 0;
int64_t Value = Target.getConstant();
+ const MCSymbol *Symbol = 0;
bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
if (!Target.isAbsolute()) {
- const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
+ Symbol = &Target.getSymA()->getSymbol();
MCSymbolData &SD = Asm.getSymbolData(*Symbol);
MCFragment *F = SD.getFragment();
@@ -560,13 +566,15 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target);
if (!RelocOnSymbol) {
- Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
+ Index = F->getParent()->getOrdinal();
MCSectionData *FSD = F->getParent();
// Offset of the symbol in the section
Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
- } else
- Index = getSymbolIndexInSymbolTable(Asm, Symbol);
+ } else {
+ UsedInReloc.insert(Symbol);
+ Index = -1;
+ }
Addend = Value;
// Compensate for the addend on i386.
if (Is64Bit)
@@ -641,15 +649,9 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
ELFRelocationEntry ERE;
- if (Is64Bit) {
- struct ELF::Elf64_Rela ERE64;
- ERE64.setSymbolAndType(Index, Type);
- ERE.r_info = ERE64.r_info;
- } else {
- struct ELF::Elf32_Rela ERE32;
- ERE32.setSymbolAndType(Index, Type);
- ERE.r_info = ERE32.r_info;
- }
+ ERE.Index = Index;
+ ERE.Type = Type;
+ ERE.Symbol = Symbol;
ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
@@ -671,11 +673,12 @@ ELFObjectWriterImpl::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
return SD.getIndex() + /* empty symbol */ 1;
// External or undefined symbol.
- return SD.getIndex() + Asm.size() + /* empty symbol */ 1;
+ return SD.getIndex() + NumRegularSections + /* empty symbol */ 1;
}
void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) {
// Build section lookup table.
+ NumRegularSections = Asm.size();
DenseMap<const MCSection*, uint8_t> SectionIndexMap;
unsigned Index = 1;
for (MCAssembler::iterator it = Asm.begin(),
@@ -698,6 +701,9 @@ void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) {
if (it->isExternal() || Symbol.isUndefined())
continue;
+ if (Symbol.isTemporary() && !UsedInReloc.count(&Symbol))
+ continue;
+
uint64_t &Entry = StringIndexMap[Symbol.getName()];
if (!Entry) {
Entry = StringTable.size();
@@ -734,6 +740,10 @@ void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) {
if (Symbol.isVariable())
continue;
+ if (Symbol.isUndefined() && !UsedInReloc.count(&Symbol)
+ && Symbol.isTemporary())
+ continue;
+
uint64_t &Entry = StringIndexMap[Symbol.getName()];
if (!Entry) {
Entry = StringTable.size();
@@ -843,13 +853,19 @@ void ELFObjectWriterImpl::WriteRelocationsFragment(const MCAssembler &Asm,
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
ELFRelocationEntry entry = Relocs[e - i - 1];
+ if (entry.Index < 0)
+ entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
+ else
+ entry.Index += LocalSymbolData.size() + 1;
if (Is64Bit) {
char buf[8];
String64(buf, entry.r_offset);
F->getContents() += StringRef(buf, 8);
- String64(buf, entry.r_info);
+ struct ELF::Elf64_Rela ERE64;
+ ERE64.setSymbolAndType(entry.Index, entry.Type);
+ String64(buf, ERE64.r_info);
F->getContents() += StringRef(buf, 8);
if (HasRelocationAddend) {
@@ -862,7 +878,9 @@ void ELFObjectWriterImpl::WriteRelocationsFragment(const MCAssembler &Asm,
String32(buf, entry.r_offset);
F->getContents() += StringRef(buf, 4);
- String32(buf, entry.r_info);
+ struct ELF::Elf32_Rela ERE32;
+ ERE32.setSymbolAndType(entry.Index, entry.Type);
+ String32(buf, ERE32.r_info);
F->getContents() += StringRef(buf, 4);
if (HasRelocationAddend) {
@@ -976,8 +994,11 @@ bool ELFObjectWriterImpl::IsFixupFullyResolved(const MCAssembler &Asm,
return !SectionB && BaseSection == SectionA;
}
-void ELFObjectWriterImpl::WriteObject(const MCAssembler &Asm,
+void ELFObjectWriterImpl::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
+ // Compute symbol table information.
+ ComputeSymbolTable(Asm);
+
CreateMetadataSections(const_cast<MCAssembler&>(Asm),
const_cast<MCAsmLayout&>(Layout));
@@ -1142,7 +1163,7 @@ bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
IsPCRel, DF);
}
-void ELFObjectWriter::WriteObject(const MCAssembler &Asm,
+void ELFObjectWriter::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
((ELFObjectWriterImpl*) Impl)->WriteObject(Asm, Layout);
}
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index ecc72c26b7..b63bedc703 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -156,22 +156,6 @@ void MCELFStreamer::InitSections() {
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!");
@@ -179,11 +163,6 @@ void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
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
@@ -520,36 +499,6 @@ void MCELFStreamer::Finish() {
SectData.setAlignment(ByteAlignment);
}
- // 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();
}
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index 4bb05350ed..61df5bb35c 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -1360,7 +1360,7 @@ bool MachObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
IsPCRel, DF);
}
-void MachObjectWriter::WriteObject(const MCAssembler &Asm,
+void MachObjectWriter::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
((MachObjectWriterImpl*) Impl)->WriteObject(Asm, Layout);
}
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index 82ccddf81d..24c517b122 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -186,7 +186,7 @@ public:
bool IsPCRel,
const MCFragment *DF) const;
- void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
};
}
@@ -703,7 +703,7 @@ bool WinCOFFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
return false;
}
-void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm,
+void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
// Assign symbol and section indexes and offsets.
Header.NumberOfSections = 0;