summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/COFF/Chunks.cpp44
-rw-r--r--lld/COFF/Chunks.h6
2 files changed, 30 insertions, 20 deletions
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 84854ab7051..9ee68460661 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -58,10 +58,8 @@ void SectionChunk::writeTo(uint8_t *Buf) {
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() {
@@ -69,8 +67,8 @@ 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();
@@ -120,11 +118,11 @@ void SectionChunk::applyReloc(uint8_t *Buf, const coff_relocation *Rel) {
// 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);
@@ -156,12 +154,6 @@ void SectionChunk::printDiscardedMessage() {
}
}
-SectionRef SectionChunk::getSectionRef() const {
- DataRefImpl Ref;
- Ref.p = uintptr_t(Header);
- return SectionRef(Ref, File->getCOFFObj());
-}
-
StringRef SectionChunk::getDebugName() {
return Sym->getName();
}
@@ -196,12 +188,10 @@ bool SectionChunk::equals(const SectionChunk *X) const {
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)
@@ -230,6 +220,22 @@ void SectionChunk::replaceWith(SectionChunk *Other) {
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.
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index f45add458a3..810793dc88c 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -149,12 +149,16 @@ public:
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,
OpenPOWER on IntegriCloud