[ELF] Add AtomLayout instead of using pair<Atom, pair<uint64_t, uint64_t>>.

llvm-svn: 172265
This commit is contained in:
Michael J. Spencer 2013-01-11 22:39:44 +00:00
parent 2a5763cd86
commit 4ffbd608cd
1 changed files with 26 additions and 19 deletions

View File

@ -203,6 +203,18 @@ private:
ELFLayoutOptions _layoutOptions; ELFLayoutOptions _layoutOptions;
}; };
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 A section contains a set of atoms that have similiar properties /// \brief A section contains a set of atoms that have similiar properties
/// The atoms that have similiar properties are merged to form a section /// The atoms that have similiar properties are merged to form a section
template<support::endianness target_endianness, template<support::endianness target_endianness,
@ -274,12 +286,12 @@ public:
case DefinedAtom::typeCode: case DefinedAtom::typeCode:
case DefinedAtom::typeData: case DefinedAtom::typeData:
case DefinedAtom::typeConstant: case DefinedAtom::typeConstant:
_atoms.push_back(std::make_pair(atom, std::make_pair(fOffset, 0))); _atoms.push_back(AtomLayout(atom, fOffset, 0));
this->_fsize = fOffset + definedAtom->size(); this->_fsize = fOffset + definedAtom->size();
this->_msize = mOffset + definedAtom->size(); this->_msize = mOffset + definedAtom->size();
break; break;
case DefinedAtom::typeZeroFill: case DefinedAtom::typeZeroFill:
_atoms.push_back(std::make_pair(atom, std::make_pair(mOffset, 0))); _atoms.push_back(AtomLayout(atom, mOffset, 0));
this->_msize = mOffset + definedAtom->size(); this->_msize = mOffset + definedAtom->size();
break; break;
default: default:
@ -303,7 +315,7 @@ public:
/// of the section /// of the section
void assignVirtualAddress(uint64_t &addr) { void assignVirtualAddress(uint64_t &addr) {
for (auto &ai : _atoms) { for (auto &ai : _atoms) {
ai.second.second = addr + ai.second.first; ai._virtualAddr = addr + ai._fileOffset;
} }
addr += this->memSize(); addr += this->memSize();
} }
@ -312,7 +324,7 @@ public:
/// gets called after the linker fixes up the section offset /// gets called after the linker fixes up the section offset
void assignOffsets(uint64_t offset) { void assignOffsets(uint64_t offset) {
for (auto &ai : _atoms) { for (auto &ai : _atoms) {
ai.second.first = offset + ai.second.first; ai._fileOffset = offset + ai._fileOffset;
} }
} }
@ -321,8 +333,8 @@ public:
/// to fix the relocation /// to fix the relocation
bool findAtomAddrByName(const StringRef name, uint64_t &addr) { bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
for (auto ai : _atoms) { for (auto ai : _atoms) {
if (ai.first->name() == name) { if (ai._atom->name() == name) {
addr = ai.second.second; addr = ai._virtualAddr;
return true; return true;
} }
} }
@ -456,7 +468,7 @@ public:
OwningPtr<FileOutputBuffer> &buffer) { OwningPtr<FileOutputBuffer> &buffer) {
uint8_t *chunkBuffer = buffer->getBufferStart(); uint8_t *chunkBuffer = buffer->getBufferStart();
for (auto &ai : _atoms) { for (auto &ai : _atoms) {
const DefinedAtom *definedAtom = llvm::dyn_cast<DefinedAtom>(ai.first); const DefinedAtom *definedAtom = llvm::dyn_cast<DefinedAtom>(ai._atom);
if (definedAtom->contentType() == DefinedAtom::typeZeroFill) if (definedAtom->contentType() == DefinedAtom::typeZeroFill)
continue; continue;
// Copy raw content of atom to file buffer. // Copy raw content of atom to file buffer.
@ -464,14 +476,14 @@ public:
uint64_t contentSize = content.size(); uint64_t contentSize = content.size();
if (contentSize == 0) if (contentSize == 0)
continue; continue;
uint8_t *atomContent = chunkBuffer + ai.second.first; uint8_t *atomContent = chunkBuffer + ai._fileOffset;
std::copy_n(content.data(), contentSize, atomContent); std::copy_n(content.data(), contentSize, atomContent);
for (auto ref = definedAtom->begin(); ref != definedAtom->end(); ++ref) { for (auto ref = definedAtom->begin(); ref != definedAtom->end(); ++ref) {
uint32_t offset = ref->offsetInAtom(); uint32_t offset = ref->offsetInAtom();
uint64_t targetAddress = 0; uint64_t targetAddress = 0;
assert(ref->target() != nullptr && "Found the target to be NULL"); assert(ref->target() != nullptr && "Found the target to be NULL");
targetAddress = writer->addressOfAtom(ref->target()); targetAddress = writer->addressOfAtom(ref->target());
uint64_t fixupAddress = writer->addressOfAtom(ai.first) + offset; uint64_t fixupAddress = writer->addressOfAtom(ai._atom) + offset;
// apply the relocation // apply the relocation
writer->kindHandler()->applyFixup(ref->kind(), writer->kindHandler()->applyFixup(ref->kind(),
ref->addend(), ref->addend(),
@ -483,8 +495,7 @@ public:
} }
/// Atom Iterators /// Atom Iterators
typedef typename std::vector<std::pair<const Atom *, typedef typename std::vector<AtomLayout>::iterator atom_iter;
std::pair<uint64_t, uint64_t>>>::iterator atom_iter;
atom_iter atoms_begin() { return _atoms.begin(); } atom_iter atoms_begin() { return _atoms.begin(); }
@ -493,12 +504,8 @@ public:
protected: protected:
int32_t _contentType; int32_t _contentType;
int32_t _contentPermissions; int32_t _contentPermissions;
SectionKind _sectionKind; SectionKind _sectionKind;
// An Atom is appended to the vector with the following fields std::vector<AtomLayout> _atoms;
// field1 : Atom
// field2 : fileoffset (initially set with a base offset of 0)
// field3 : virtual address
std::vector<std::pair<const Atom *, std::pair<uint64_t, uint64_t>>> _atoms;
ELFLayout::SegmentType _segmentType; ELFLayout::SegmentType _segmentType;
int64_t _entSize; int64_t _entSize;
int64_t _shInfo; int64_t _shInfo;
@ -2126,7 +2133,7 @@ void ELFExecutableWriter<target_endianness, max_align, is64Bits>
section = section =
llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(*si); llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(*si);
for (auto ai = section->atoms_begin(); ai != section->atoms_end(); ++ai) { for (auto ai = section->atoms_begin(); ai != section->atoms_end(); ++ai) {
_symtab->addSymbol(ai->first, section->ordinal(), ai->second.second); _symtab->addSymbol(ai->_atom, section->ordinal(), ai->_virtualAddr);
} }
} }
} }
@ -2160,7 +2167,7 @@ void ELFExecutableWriter<target_endianness, max_align, is64Bits>
continue; continue;
section = cast<Section<target_endianness, max_align, is64Bits>>(*si); section = cast<Section<target_endianness, max_align, is64Bits>>(*si);
for (auto ai = section->atoms_begin(); ai != section->atoms_end(); ++ai) { for (auto ai = section->atoms_begin(); ai != section->atoms_end(); ++ai) {
_atomToAddressMap[ai->first] = (ai)->second.second; _atomToAddressMap[ai->_atom] = (ai)->_virtualAddr;
} }
} }
/// build the atomToAddressMap that contains absolute symbols too /// build the atomToAddressMap that contains absolute symbols too