#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/StringSaver.h"
#include <vector>
using namespace llvm;
/// @name Symbol Table Data
/// @{
- StringTableBuilder StrTabBuilder;
+ BumpPtrAllocator Alloc;
+ StringSaver VersionSymSaver{Alloc};
+ StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
/// @}
uint32_t StringIndex, ELFSymbolData &MSD,
const MCAsmLayout &Layout) {
const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
- assert((!Symbol.getFragment() ||
- (Symbol.getFragment()->getParent() == &Symbol.getSection())) &&
- "The symbol's section doesn't match the fragment's symbol");
const MCSymbolELF *Base =
cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
// In general, ELF has no relocations for -B. It can only represent (A + C)
// or (A + C - R). If B = R + K and the relocation is not pcrel, we can
// replace B to implement it: (A - R - K + C)
- if (IsPCRel)
- Asm.getContext().reportFatalError(
+ if (IsPCRel) {
+ Asm.getContext().reportError(
Fixup.getLoc(),
"No relocation available to represent this relative expression");
+ return;
+ }
const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
- if (SymB.isUndefined())
- Asm.getContext().reportFatalError(
+ if (SymB.isUndefined()) {
+ Asm.getContext().reportError(
Fixup.getLoc(),
Twine("symbol '") + SymB.getName() +
"' can not be undefined in a subtraction expression");
+ return;
+ }
assert(!SymB.isAbsolute() && "Should have been folded");
const MCSection &SecB = SymB.getSection();
- if (&SecB != &FixupSection)
- Asm.getContext().reportFatalError(
+ if (&SecB != &FixupSection) {
+ Asm.getContext().reportError(
Fixup.getLoc(), "Cannot represent a difference across sections");
+ return;
+ }
- if (::isWeak(SymB))
- Asm.getContext().reportFatalError(
+ if (::isWeak(SymB)) {
+ Asm.getContext().reportError(
Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol");
+ return;
+ }
uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
uint64_t K = SymBOffset - FixupOffset;
Renames.count(&Symbol)))
continue;
- if (Symbol.isTemporary() && Symbol.isUndefined())
- Ctx.reportFatalError(SMLoc(), "Undefined temporary");
+ if (Symbol.isTemporary() && Symbol.isUndefined()) {
+ Ctx.reportError(SMLoc(), "Undefined temporary symbol");
+ continue;
+ }
ELFSymbolData MSD;
MSD.Symbol = cast<MCSymbolELF>(&Symbol);
Buf += Name.substr(0, Pos);
unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
Buf += Name.substr(Pos + Skip);
- Name = Buf;
+ Name = VersionSymSaver.save(Buf.c_str());
}
}
// Sections have their own string table
- if (Symbol.getType() != ELF::STT_SECTION)
- MSD.Name = StrTabBuilder.add(Name);
+ if (Symbol.getType() != ELF::STT_SECTION) {
+ MSD.Name = Name;
+ StrTabBuilder.add(Name);
+ }
if (Local)
LocalSymbolData.push_back(MSD);
for (const std::string &Name : FileNames)
StrTabBuilder.add(Name);
- StrTabBuilder.finalize(StringTableBuilder::ELF);
+ StrTabBuilder.finalize();
for (const std::string &Name : FileNames)
Writer.writeSymbol(StrTabBuilder.getOffset(Name),
const MCSectionELF &Sec) {
std::vector<ELFRelocationEntry> &Relocs = Relocations[&Sec];
- // Sort the relocation entries. Most targets just sort by Offset, but some
- // (e.g., MIPS) have additional constraints.
+ // We record relocations by pushing to the end of a vector. Reverse the vector
+ // to get the relocations in the order they were created.
+ // In most cases that is not important, but it can be for special sections
+ // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
+ std::reverse(Relocs.begin(), Relocs.end());
+
+ // Sort the relocation entries. MIPS needs this.
TargetObjectWriter->sortRelocs(Asm, Relocs);
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {