PECOFF: Define and use BaseReloc type instead of std::pair.

"first" and "second" are not easy to memorize.
Define a type to use meaningful names.

llvm-svn: 231614
This commit is contained in:
Rui Ueyama 2015-03-08 22:49:27 +00:00
parent 7e621e9d5e
commit f46b190465
1 changed files with 29 additions and 33 deletions

View File

@ -262,12 +262,15 @@ private:
uint64_t _memAlign; uint64_t _memAlign;
}; };
struct BaseReloc {
BaseReloc(uint64_t a, llvm::COFF::BaseRelocationType t) : addr(a), type(t) {}
uint64_t addr;
llvm::COFF::BaseRelocationType type;
};
/// An AtomChunk represents a section containing atoms. /// An AtomChunk represents a section containing atoms.
class AtomChunk : public SectionChunk { class AtomChunk : public SectionChunk {
public: public:
typedef std::pair<uint64_t, llvm::COFF::BaseRelocationType> BaseRelocation;
typedef std::vector<BaseRelocation> BaseRelocationList;
AtomChunk(const PECOFFLinkingContext &ctx, StringRef name, AtomChunk(const PECOFFLinkingContext &ctx, StringRef name,
const std::vector<const DefinedAtom *> &atoms); const std::vector<const DefinedAtom *> &atoms);
@ -291,7 +294,7 @@ public:
uint64_t imageBaseAddress); uint64_t imageBaseAddress);
void printAtomAddresses(uint64_t baseAddr) const; void printAtomAddresses(uint64_t baseAddr) const;
void addBaseRelocations(BaseRelocationList &relocSites) const; void addBaseRelocations(std::vector<BaseReloc> &relocSites) const;
void setVirtualAddress(uint32_t rva) override; void setVirtualAddress(uint32_t rva) override;
uint64_t getAtomVirtualAddress(StringRef name) const; uint64_t getAtomVirtualAddress(StringRef name) const;
@ -355,10 +358,6 @@ class BaseRelocChunk : public SectionChunk {
typedef std::vector<std::unique_ptr<Chunk> > ChunkVectorT; typedef std::vector<std::unique_ptr<Chunk> > ChunkVectorT;
public: public:
typedef std::vector<std::pair<uint16_t, llvm::COFF::BaseRelocationType>>
BaseRelocations;
typedef std::map<uint64_t, BaseRelocations> RelocationBlocks;
BaseRelocChunk(ChunkVectorT &chunks, const PECOFFLinkingContext &ctx) BaseRelocChunk(ChunkVectorT &chunks, const PECOFFLinkingContext &ctx)
: SectionChunk(kindSection, ".reloc", characteristics, ctx), : SectionChunk(kindSection, ".reloc", characteristics, ctx),
_ctx(ctx), _contents(createContents(chunks)) {} _ctx(ctx), _contents(createContents(chunks)) {}
@ -380,13 +379,12 @@ private:
// Returns a list of RVAs that needs to be relocated if the binary is loaded // Returns a list of RVAs that needs to be relocated if the binary is loaded
// at an address different from its preferred one. // at an address different from its preferred one.
AtomChunk::BaseRelocationList listRelocSites(ChunkVectorT &chunks) const; std::vector<BaseReloc> listRelocSites(ChunkVectorT &chunks) const;
// Create the content of a relocation block. // Create the content of a relocation block.
std::vector<uint8_t> std::vector<uint8_t>
createBaseRelocBlock(uint64_t pageAddr, createBaseRelocBlock(uint64_t pageAddr, const BaseReloc *begin,
const AtomChunk::BaseRelocation *begin, const BaseReloc *end) const;
const AtomChunk::BaseRelocation *end) const;
const PECOFFLinkingContext &_ctx; const PECOFFLinkingContext &_ctx;
std::vector<uint8_t> _contents; std::vector<uint8_t> _contents;
@ -781,7 +779,7 @@ void AtomChunk::printAtomAddresses(uint64_t baseAddr) const {
/// to be fixed up if image base is relocated. The only relocation type that /// to be fixed up if image base is relocated. The only relocation type that
/// needs to be fixed is DIR32 on i386. REL32 is not (and should not be) /// needs to be fixed is DIR32 on i386. REL32 is not (and should not be)
/// fixed up because it's PC-relative. /// fixed up because it's PC-relative.
void AtomChunk::addBaseRelocations(BaseRelocationList &relocSites) const { void AtomChunk::addBaseRelocations(std::vector<BaseReloc> &relocSites) const {
for (const auto *layout : _atomLayouts) { for (const auto *layout : _atomLayouts) {
const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom); const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
for (const Reference *ref : *atom) { for (const Reference *ref : *atom) {
@ -802,20 +800,20 @@ void AtomChunk::addBaseRelocations(BaseRelocationList &relocSites) const {
case llvm::COFF::IMAGE_FILE_MACHINE_I386: case llvm::COFF::IMAGE_FILE_MACHINE_I386:
if (ref->kindValue() == llvm::COFF::IMAGE_REL_I386_DIR32) if (ref->kindValue() == llvm::COFF::IMAGE_REL_I386_DIR32)
relocSites.push_back( relocSites.push_back(
std::make_pair(address, llvm::COFF::IMAGE_REL_BASED_HIGHLOW)); BaseReloc(address, llvm::COFF::IMAGE_REL_BASED_HIGHLOW));
break; break;
case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
if (ref->kindValue() == llvm::COFF::IMAGE_REL_AMD64_ADDR64) if (ref->kindValue() == llvm::COFF::IMAGE_REL_AMD64_ADDR64)
relocSites.push_back( relocSites.push_back(
std::make_pair(address, llvm::COFF::IMAGE_REL_BASED_DIR64)); BaseReloc(address, llvm::COFF::IMAGE_REL_BASED_DIR64));
break; break;
case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
if (ref->kindValue() == llvm::COFF::IMAGE_REL_ARM_ADDR32) if (ref->kindValue() == llvm::COFF::IMAGE_REL_ARM_ADDR32)
relocSites.push_back( relocSites.push_back(
std::make_pair(address, llvm::COFF::IMAGE_REL_BASED_HIGHLOW)); BaseReloc(address, llvm::COFF::IMAGE_REL_BASED_HIGHLOW));
else if (ref->kindValue() == llvm::COFF::IMAGE_REL_ARM_MOV32T) else if (ref->kindValue() == llvm::COFF::IMAGE_REL_ARM_MOV32T)
relocSites.push_back( relocSites.push_back(
std::make_pair(address, llvm::COFF::IMAGE_REL_BASED_ARM_MOV32T)); BaseReloc(address, llvm::COFF::IMAGE_REL_BASED_ARM_MOV32T));
break; break;
} }
} }
@ -962,24 +960,23 @@ SectionHeaderTableChunk::createSectionHeader(SectionChunk *chunk) {
std::vector<uint8_t> std::vector<uint8_t>
BaseRelocChunk::createContents(ChunkVectorT &chunks) const { BaseRelocChunk::createContents(ChunkVectorT &chunks) const {
std::vector<uint8_t> contents; std::vector<uint8_t> contents;
AtomChunk::BaseRelocationList relocSites = listRelocSites(chunks); std::vector<BaseReloc> relocSites = listRelocSites(chunks);
uint64_t mask = _ctx.getPageSize() - 1; uint64_t mask = _ctx.getPageSize() - 1;
parallel_sort(relocSites.begin(), relocSites.end(), parallel_sort(relocSites.begin(), relocSites.end(),
[&](const AtomChunk::BaseRelocation &a, [=](const BaseReloc &a, const BaseReloc &b) {
const AtomChunk::BaseRelocation &b) { return (a.addr & ~mask) < (b.addr & ~mask);
return (a.first & ~mask) < (b.first & ~mask);
}); });
// Base relocations for the same memory page are grouped together // Base relocations for the same memory page are grouped together
// and passed to createBaseRelocBlock. // and passed to createBaseRelocBlock.
for (size_t i = 0, e = relocSites.size(); i < e;) { for (size_t i = 0, e = relocSites.size(); i < e;) {
const AtomChunk::BaseRelocation *begin = &relocSites[i]; const BaseReloc *begin = &relocSites[i];
uint64_t pageAddr = (begin->first & ~mask); uint64_t pageAddr = (begin->addr & ~mask);
for (++i; i < e; ++i) for (++i; i < e; ++i)
if ((relocSites[i].first & ~mask) != pageAddr) if ((relocSites[i].addr & ~mask) != pageAddr)
break; break;
const AtomChunk::BaseRelocation *end = &relocSites[i]; const BaseReloc *end = &relocSites[i];
std::vector<uint8_t> block = createBaseRelocBlock(pageAddr, begin, end); std::vector<uint8_t> block = createBaseRelocBlock(pageAddr, begin, end);
contents.insert(contents.end(), block.begin(), block.end()); contents.insert(contents.end(), block.begin(), block.end());
} }
@ -988,9 +985,9 @@ BaseRelocChunk::createContents(ChunkVectorT &chunks) const {
// Returns a list of RVAs that needs to be relocated if the binary is loaded // Returns a list of RVAs that needs to be relocated if the binary is loaded
// at an address different from its preferred one. // at an address different from its preferred one.
AtomChunk::BaseRelocationList std::vector<BaseReloc>
BaseRelocChunk::listRelocSites(ChunkVectorT &chunks) const { BaseRelocChunk::listRelocSites(ChunkVectorT &chunks) const {
AtomChunk::BaseRelocationList ret; std::vector<BaseReloc> ret;
for (auto &cp : chunks) for (auto &cp : chunks)
if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp)) if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp))
chunk->addBaseRelocations(ret); chunk->addBaseRelocations(ret);
@ -999,10 +996,9 @@ BaseRelocChunk::listRelocSites(ChunkVectorT &chunks) const {
// Create the content of a relocation block. // Create the content of a relocation block.
std::vector<uint8_t> std::vector<uint8_t>
BaseRelocChunk::createBaseRelocBlock( BaseRelocChunk::createBaseRelocBlock(uint64_t pageAddr,
uint64_t pageAddr, const BaseReloc *begin,
const AtomChunk::BaseRelocation *begin, const BaseReloc *end) const {
const AtomChunk::BaseRelocation *end) const {
// Relocation blocks should be padded with IMAGE_REL_I386_ABSOLUTE to be // Relocation blocks should be padded with IMAGE_REL_I386_ABSOLUTE to be
// aligned to a DWORD size boundary. // aligned to a DWORD size boundary.
uint32_t size = llvm::RoundUpToAlignment( uint32_t size = llvm::RoundUpToAlignment(
@ -1021,8 +1017,8 @@ BaseRelocChunk::createBaseRelocBlock(
ptr += sizeof(ulittle32_t); ptr += sizeof(ulittle32_t);
uint64_t mask = _ctx.getPageSize() - 1; uint64_t mask = _ctx.getPageSize() - 1;
for (const AtomChunk::BaseRelocation *i = begin; i < end; ++i) { for (const BaseReloc *i = begin; i < end; ++i) {
write16le(ptr, (i->second << 12) | (i->first & mask)); write16le(ptr, (i->type << 12) | (i->addr & mask));
ptr += sizeof(ulittle16_t); ptr += sizeof(ulittle16_t);
} }
return contents; return contents;