}
void MergeChunk::finalizeContents() {
- if (!Finalized) {
- for (SectionChunk *C : Sections)
- if (C->Live)
- Builder.add(toStringRef(C->getContents()));
- Builder.finalize();
- Finalized = true;
- }
+ assert(!Finalized && "should only finalize once");
+ for (SectionChunk *C : Sections)
+ if (C->Live)
+ Builder.add(toStringRef(C->getContents()));
+ Builder.finalize();
+ Finalized = true;
+}
+void MergeChunk::assignSubsectionRVAs() {
for (SectionChunk *C : Sections) {
if (!C->Live)
continue;
// before calling this function.
virtual void writeTo(uint8_t *Buf) const {}
- // Called by the writer after an RVA is assigned, but before calling
- // getSize().
- virtual void finalizeContents() {}
-
// The writer sets and uses the addresses. In practice, PE images cannot be
// larger than 2GB. Chunks are always laid as part of the image, so Chunk RVAs
// can be stored with 32 bits.
public:
MergeChunk(uint32_t Alignment);
static void addSection(SectionChunk *C);
- void finalizeContents() override;
+ void finalizeContents();
+ void assignSubsectionRVAs();
uint32_t getOutputCharacteristics() const override;
StringRef getSectionName() const override { return ".rdata"; }
}
void Writer::createMiscChunks() {
- for (MergeChunk *P : MergeChunk::Instances)
- if (P)
+ for (MergeChunk *P : MergeChunk::Instances) {
+ if (P) {
+ P->finalizeContents();
RdataSec->addChunk(P);
+ }
+ }
// Create thunks for locally-dllimported symbols.
if (!Symtab->LocalImportChunks.empty()) {
VirtualSize += Padding;
VirtualSize = alignTo(VirtualSize, C->getAlignment());
C->setRVA(RVA + VirtualSize);
- C->finalizeContents();
VirtualSize += C->getSize();
if (C->hasData())
RawSize = alignTo(VirtualSize, SectorSize);
FileSize += alignTo(RawSize, SectorSize);
}
SizeOfImage = alignTo(RVA, PageSize);
+
+ // Assign addresses to sections in MergeChunks.
+ for (MergeChunk *MC : MergeChunk::Instances)
+ if (MC)
+ MC->assignSubsectionRVAs();
}
template <typename PEHeaderTy> void Writer::writeHeader() {