memcpy(Buf + FileOff, Data.data(), Data.size());
// Apply relocations.
- for (const auto &I : getSectionRef().relocations()) {
- const coff_relocation *Rel = File->getCOFFObj()->getCOFFRelocation(I);
+ for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E; ++Rel)
applyReloc(Buf, Rel);
- }
}
void SectionChunk::mark() {
Live = true;
// Mark all symbols listed in the relocation table for this section.
- for (const auto &I : getSectionRef().relocations()) {
- const coff_relocation *Rel = File->getCOFFObj()->getCOFFRelocation(I);
+ for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E;
+ ++Rel) {
SymbolBody *B = File->getSymbolBody(Rel->SymbolTableIndex);
if (auto *Def = dyn_cast<Defined>(B))
Def->markLive();
// which need to be fixed by the loader if load-time relocation is needed.
// Only called when base relocation is enabled.
void SectionChunk::getBaserels(std::vector<uint32_t> *Res, Defined *ImageBase) {
- for (const auto &I : getSectionRef().relocations()) {
+ for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E;
+ ++Rel) {
// ADDR64 relocations contain absolute addresses.
// Symbol __ImageBase is special -- it's an absolute symbol, but its
// address never changes even if image is relocated.
- const coff_relocation *Rel = File->getCOFFObj()->getCOFFRelocation(I);
if (Rel->Type != IMAGE_REL_AMD64_ADDR64)
continue;
SymbolBody *Body = File->getSymbolBody(Rel->SymbolTableIndex);
}
}
-SectionRef SectionChunk::getSectionRef() const {
- DataRefImpl Ref;
- Ref.p = uintptr_t(Header);
- return SectionRef(Ref, File->getCOFFObj());
-}
-
StringRef SectionChunk::getDebugName() {
return Sym->getName();
}
return false;
// Compare relocations
- auto Range1 = getSectionRef().relocations();
- auto Range2 = X->getSectionRef().relocations();
- auto End = Range1.end();
- for (auto I = Range1.begin(), J = Range2.begin(); I != End; ++I, ++J) {
- const coff_relocation *Rel1 = File->getCOFFObj()->getCOFFRelocation(*I);
- const coff_relocation *Rel2 = X->File->getCOFFObj()->getCOFFRelocation(*J);
+ const coff_relocation *Rel1 = relBegin();
+ const coff_relocation *End = relEnd();
+ const coff_relocation *Rel2 = X->relBegin();
+ for (; Rel1 != End; ++Rel1, ++Rel2) {
if (Rel1->Type != Rel2->Type)
return false;
if (Rel1->VirtualAddress != Rel2->VirtualAddress)
Live = false;
}
+const coff_relocation *SectionChunk::relBegin() const {
+ if (!Reloc) {
+ DataRefImpl Ref;
+ Ref.p = uintptr_t(Header);
+ SectionRef Sref(Ref, File->getCOFFObj());
+ relocation_iterator It = Sref.relocation_begin();
+ Reloc = File->getCOFFObj()->getCOFFRelocation(*It);
+ }
+ return Reloc;
+}
+
+const coff_relocation *SectionChunk::relEnd() const {
+ const coff_relocation *I = relBegin();
+ return I + Header->NumberOfRelocations;
+}
+
CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
// Common symbols are aligned on natural boundaries up to 32 bytes.
// This is what MSVC link.exe does.
private:
void mark() override;
- SectionRef getSectionRef() const;
void applyReloc(uint8_t *Buf, const coff_relocation *Rel);
// A file this chunk was created from.
ObjectFile *File;
+ // A raw pointer to the relocation table.
+ mutable const coff_relocation *Reloc = nullptr;
+ const coff_relocation *relBegin() const;
+ const coff_relocation *relEnd() const;
+
// A pointer pointing to a replacement for this chunk.
// Initially it points to "this" object. If this chunk is merged
// with other chunk by ICF, it points to another chunk,