[lld] r173874 - [ELF] Make AtomLayout more accessible.
Michael J. Spencer
bigcheesegs at gmail.com
Tue Jan 29 17:25:06 PST 2013
Author: mspencer
Date: Tue Jan 29 19:25:06 2013
New Revision: 173874
URL: http://llvm.org/viewvc/llvm-project?rev=173874&view=rev
Log:
[ELF] Make AtomLayout more accessible.
This is needed to allow constant time access to the final layout of atoms.
Modified:
lld/trunk/lib/ReaderWriter/ELF/Chunk.h
lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
lld/trunk/lib/ReaderWriter/ELF/Layout.h
lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
Modified: lld/trunk/lib/ReaderWriter/ELF/Chunk.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Chunk.h?rev=173874&r1=173873&r2=173874&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Chunk.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Chunk.h Tue Jan 29 19:25:06 2013
@@ -55,7 +55,6 @@ public:
Kind kind() const { return _kind; }
uint64_t fileSize() const { return _fsize; }
uint64_t align2() const { return _align2; }
- void appendAtom() const;
// The ordinal value of the chunk
uint64_t ordinal() const { return _ordinal;}
Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=173874&r1=173873&r2=173874&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Tue Jan 29 19:25:06 2013
@@ -132,34 +132,14 @@ public:
typedef std::unordered_map<SegmentKey, Segment<ELFT> *,
SegmentHashKey> SegmentMapT;
- /// \brief All absolute atoms are created in the ELF Layout by using
- /// an AbsoluteAtomPair. Contains a pair of AbsoluteAtom and the
- /// value which is the address of the absolute atom
- class AbsoluteAtomPair {
- public:
- AbsoluteAtomPair(const AbsoluteAtom *a, int64_t value)
- : _absoluteAtom(a)
- , _value(value) { }
-
- const AbsoluteAtom *absoluteAtom() { return _absoluteAtom; }
- int64_t value() const { return _value; }
- void setValue(int64_t val) { _value = val; }
-
- private:
- const AbsoluteAtom *_absoluteAtom;
- int64_t _value;
- };
-
/// \brief find a absolute atom pair given a absolute atom name
struct FindByName {
const std::string _name;
FindByName(StringRef name) : _name(name) {}
- bool operator()(AbsoluteAtomPair& j) {
- return j.absoluteAtom()->name() == _name;
- }
+ bool operator()(const AtomLayout *j) { return j->_atom->name() == _name; }
};
- typedef typename std::vector<AbsoluteAtomPair>::iterator AbsoluteAtomIterT;
+ typedef typename std::vector<AtomLayout *>::iterator AbsoluteAtomIterT;
DefaultLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {}
@@ -181,7 +161,7 @@ public:
static bool hasOutputSegment(Section<ELFT> *section);
// Adds an atom to the section
- virtual error_code addAtom(const Atom *atom);
+ virtual ErrorOr<const AtomLayout &> addAtom(const Atom *atom);
/// \brief Find an output Section given a section name.
MergedSections<ELFT> *findOutputSection(StringRef name) {
@@ -270,7 +250,7 @@ private:
Header<ELFT> *_header;
ProgramHeader<ELFT> *_programHeader;
RelocationTable<ELFT> *_relocationTable;
- std::vector<AbsoluteAtomPair> _absoluteAtoms;
+ std::vector<AtomLayout *> _absoluteAtoms;
llvm::BumpPtrAllocator _allocator;
const ELFTargetInfo &_targetInfo;
};
@@ -408,10 +388,14 @@ DefaultLayout<ELFT>::hasOutputSegment(Se
}
}
-template<class ELFT>
-error_code
-DefaultLayout<ELFT>::addAtom(const Atom *atom) {
+template <class ELFT>
+ErrorOr<const AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) {
if (const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom)) {
+ // HACK: Ignore undefined atoms. We need to adjust the interface so that
+ // undefined atoms can still be included in the output symbol table for
+ // -noinhibit-exec.
+ if (definedAtom->contentType() == DefinedAtom::typeUnknown)
+ return make_error_code(llvm::errc::invalid_argument);
const StringRef sectionName = getSectionName(
definedAtom->customSectionName(), definedAtom->contentType());
const DefinedAtom::ContentPermissions permissions =
@@ -432,7 +416,7 @@ DefaultLayout<ELFT>::addAtom(const Atom
} else {
section = _sectionMap[sectionKey];
}
- section->appendAtom(atom);
+ return section->appendAtom(atom);
// Add runtime relocations to the .rela section.
for (const auto &reloc : *definedAtom)
if (_targetInfo.isRuntimeRelocation(*definedAtom, *reloc))
@@ -440,12 +424,12 @@ DefaultLayout<ELFT>::addAtom(const Atom
} else if (const AbsoluteAtom *absoluteAtom = dyn_cast<AbsoluteAtom>(atom)) {
// Absolute atoms are not part of any section, they are global for the whole
// link
- _absoluteAtoms.push_back(AbsoluteAtomPair(absoluteAtom,
- absoluteAtom->value()));
+ _absoluteAtoms.push_back(
+ new (_allocator) AtomLayout(absoluteAtom, 0, absoluteAtom->value()));
+ return *_absoluteAtoms.back();
} else {
llvm_unreachable("Only absolute / defined atoms can be added here");
}
- return error_code::success();
}
/// Merge sections with the same name into a MergedSections
Modified: lld/trunk/lib/ReaderWriter/ELF/Layout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Layout.h?rev=173874&r1=173873&r2=173874&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Layout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Layout.h Tue Jan 29 19:25:06 2013
@@ -17,10 +17,23 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
+#include "llvm/Support/ErrorOr.h"
namespace lld {
namespace elf {
-/// \brief The Layout is an abstract class for managing the final layout for
+struct AtomLayout {
+ AtomLayout(const Atom *a, uint64_t fileOff, uint64_t virAddr)
+ : _atom(a), _fileOffset(fileOff), _virtualAddr(virAddr) {
+ }
+
+ AtomLayout() : _atom(nullptr), _fileOffset(0), _virtualAddr(0) {}
+
+ const Atom *_atom;
+ uint64_t _fileOffset;
+ uint64_t _virtualAddr;
+};
+
+/// \brief The ELFLayout is an abstract class for managing the final layout for
/// the kind of binaries(Shared Libraries / Relocatables / Executables 0
/// Each architecture (Hexagon, PowerPC, MIPS) would have a concrete
/// subclass derived from Layout for generating each binary thats
@@ -37,8 +50,10 @@ public:
(const StringRef name,
int32_t contentType,
int32_t contentPerm) = 0;
- /// append the Atom to the layout and create appropriate sections
- virtual error_code addAtom(const Atom *atom) = 0;
+ /// \brief Append the Atom to the layout and create appropriate sections.
+ /// \returns A reference to the atom layout or an error. The atom layout will
+ /// be updated as linking progresses.
+ virtual ErrorOr<const AtomLayout &> addAtom(const Atom *atom) = 0;
/// find the Atom Address in the current layout
virtual bool findAtomAddrByName(const StringRef name,
uint64_t &addr) = 0;
@@ -54,18 +69,6 @@ public:
virtual ~Layout() { }
};
-
-struct AtomLayout {
- AtomLayout(const Atom *a, uint64_t fileOff, uint64_t virAddr)
- : _atom(a), _fileOffset(fileOff), _virtualAddr(virAddr) {}
-
- AtomLayout()
- : _atom(nullptr), _fileOffset(0), _virtualAddr(0) {}
-
- const Atom *_atom;
- uint64_t _fileOffset;
- uint64_t _virtualAddr;
-};
} // end namespace elf
} // end namespace lld
Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=173874&r1=173873&r2=173874&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Tue Jan 29 19:25:06 2013
@@ -60,14 +60,14 @@ public:
// \brief Append an atom to a Section. The atom gets pushed into a vector
// contains the atom, the atom file offset, the atom virtual address
// the atom file offset is aligned appropriately as set by the Reader
- void appendAtom(const Atom *atom);
+ const AtomLayout &appendAtom(const Atom *atom);
/// \brief Set the virtual address of each Atom in the Section. This
/// routine gets called after the linker fixes up the virtual address
/// of the section
inline void assignVirtualAddress(uint64_t &addr) {
for (auto &ai : _atoms) {
- ai._virtualAddr = addr + ai._fileOffset;
+ ai->_virtualAddr = addr + ai->_fileOffset;
}
addr += this->memSize();
}
@@ -76,7 +76,7 @@ public:
/// gets called after the linker fixes up the section offset
inline void assignOffsets(uint64_t offset) {
for (auto &ai : _atoms) {
- ai._fileOffset = offset + ai._fileOffset;
+ ai->_fileOffset = offset + ai->_fileOffset;
}
}
@@ -85,8 +85,8 @@ public:
/// to fix the relocation
inline bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
for (auto ai : _atoms) {
- if (ai._atom->name() == name) {
- addr = ai._virtualAddr;
+ if (ai->_atom->name() == name) {
+ addr = ai->_virtualAddr;
return true;
}
}
@@ -159,7 +159,7 @@ public:
void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
/// Atom Iterators
- typedef typename std::vector<AtomLayout>::iterator atom_iter;
+ typedef typename std::vector<AtomLayout *>::iterator atom_iter;
range<atom_iter> atoms() { return _atoms; }
@@ -167,11 +167,12 @@ protected:
int32_t _contentType;
int32_t _contentPermissions;
SectionKind _sectionKind;
- std::vector<AtomLayout> _atoms;
+ std::vector<AtomLayout *> _atoms;
Layout::SegmentType _segmentType;
int64_t _entSize;
int64_t _shInfo;
int64_t _link;
+ llvm::BumpPtrAllocator _alloc;
};
// Create a section object, the section is set to the default type if the
@@ -207,9 +208,8 @@ Section<ELFT>::alignOffset(uint64_t offs
// \brief Append an atom to a Section. The atom gets pushed into a vector
// contains the atom, the atom file offset, the atom virtual address
// the atom file offset is aligned appropriately as set by the Reader
-template<class ELFT>
-void
-Section<ELFT>::appendAtom(const Atom *atom) {
+template <class ELFT>
+const AtomLayout &Section<ELFT>::appendAtom(const Atom *atom) {
Atom::Definition atomType = atom->definition();
const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
@@ -229,7 +229,7 @@ Section<ELFT>::appendAtom(const Atom *at
case DefinedAtom::typeGOT:
case DefinedAtom::typeStub:
case DefinedAtom::typeResolver:
- _atoms.push_back(AtomLayout(atom, fOffset, 0));
+ _atoms.push_back(new (_alloc) AtomLayout(atom, fOffset, 0));
this->_fsize = fOffset + definedAtom->size();
this->_msize = mOffset + definedAtom->size();
DEBUG_WITH_TYPE("Section",
@@ -238,13 +238,12 @@ Section<ELFT>::appendAtom(const Atom *at
<< fOffset << "\n");
break;
case DefinedAtom::typeZeroFill:
- _atoms.push_back(AtomLayout(atom, mOffset, 0));
+ _atoms.push_back(new (_alloc) AtomLayout(atom, mOffset, 0));
this->_msize = mOffset + definedAtom->size();
break;
default:
- this->_fsize = fOffset + definedAtom->size();
- this->_msize = mOffset + definedAtom->size();
- break;
+ llvm::dbgs() << definedAtom->contentType() << "\n";
+ llvm_unreachable("Uexpected content type.");
}
break;
default:
@@ -255,6 +254,8 @@ Section<ELFT>::appendAtom(const Atom *at
// std::max doesnot support uint64_t
if (this->_align2 < align2)
this->_align2 = align2;
+
+ return *_atoms.back();
}
/// \brief Get the section flags, defined by the permissions of the section
@@ -345,9 +346,9 @@ void Section<ELFT>::write(ELFWriter *wri
uint8_t *chunkBuffer = buffer.getBufferStart();
for (auto &ai : _atoms) {
DEBUG_WITH_TYPE("Section",
- llvm::dbgs() << "Writing atom: " << ai._atom->name()
- << " | " << ai._fileOffset << "\n");
- const DefinedAtom *definedAtom = cast<DefinedAtom>(ai._atom);
+ llvm::dbgs() << "Writing atom: " << ai->_atom->name()
+ << " | " << ai->_fileOffset << "\n");
+ const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom);
if (definedAtom->contentType() == DefinedAtom::typeZeroFill)
continue;
// Copy raw content of atom to file buffer.
@@ -355,14 +356,14 @@ void Section<ELFT>::write(ELFWriter *wri
uint64_t contentSize = content.size();
if (contentSize == 0)
continue;
- uint8_t *atomContent = chunkBuffer + ai._fileOffset;
+ uint8_t *atomContent = chunkBuffer + ai->_fileOffset;
std::copy_n(content.data(), contentSize, atomContent);
for (const auto ref : *definedAtom) {
uint32_t offset = ref->offsetInAtom();
uint64_t targetAddress = 0;
assert(ref->target() != nullptr && "Found the target to be NULL");
targetAddress = writer->addressOfAtom(ref->target());
- uint64_t fixupAddress = writer->addressOfAtom(ai._atom) + offset;
+ uint64_t fixupAddress = writer->addressOfAtom(ai->_atom) + offset;
// apply the relocation
writer->kindHandler()->applyFixup(ref->kind(),
ref->addend(),
Modified: lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.cpp?rev=173874&r1=173873&r2=173874&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.cpp Tue Jan 29 19:25:06 2013
@@ -97,7 +97,7 @@ void ExecutableWriter<ELFT>::buildSymbol
for (auto sec : _layout->sections())
if (auto section = dyn_cast<Section<ELFT>>(sec))
for (const auto &atom : section->atoms())
- _symtab->addSymbol(atom._atom, section->ordinal(), atom._virtualAddr);
+ _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
}
template<class ELFT>
@@ -106,7 +106,7 @@ ExecutableWriter<ELFT>::addAbsoluteUndef
// add all the absolute symbols that the layout contains to the output symbol
// table
for (auto &atom : _layout->absoluteAtoms())
- _symtab->addSymbol(atom.absoluteAtom(), ELF::SHN_ABS, atom.value());
+ _symtab->addSymbol(atom->_atom, ELF::SHN_ABS, atom->_virtualAddr);
for (const UndefinedAtom *a : file.undefined())
_symtab->addSymbol(a, ELF::SHN_UNDEF);
}
@@ -116,10 +116,10 @@ void ExecutableWriter<ELFT>::buildAtomTo
for (auto sec : _layout->sections())
if (auto section = dyn_cast<Section<ELFT>>(sec))
for (const auto &atom : section->atoms())
- _atomToAddressMap[atom._atom] = atom._virtualAddr;
+ _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
// build the atomToAddressMap that contains absolute symbols too
for (auto &atom : _layout->absoluteAtoms())
- _atomToAddressMap[atom.absoluteAtom()] = atom.value();
+ _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
}
template<class ELFT>
@@ -187,11 +187,11 @@ void ExecutableWriter<ELFT>::finalizeDef
StringRef sec) -> void {
auto section = _layout->findOutputSection(sec);
if (section) {
- start->setValue(section->virtualAddr());
- end->setValue(section->virtualAddr() + section->memSize());
+ (*start)->_virtualAddr = section->virtualAddr();
+ (*end)->_virtualAddr = section->virtualAddr() + section->memSize();
} else {
- start->setValue(0);
- end->setValue(0);
+ (*start)->_virtualAddr = 0;
+ (*end)->_virtualAddr = 0;
}
};
@@ -210,10 +210,10 @@ void ExecutableWriter<ELFT>::finalizeDef
assert(!(phe == _programHeader->end()) &&
"Can't find a data segment in the program header!");
- bssStartAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_filesz);
- bssEndAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
- underScoreEndAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
- endAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
+ (*bssStartAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_filesz;
+ (*bssEndAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
+ (*underScoreEndAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
+ (*endAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
}
template<class ELFT>
More information about the llvm-commits
mailing list