diff options
-rw-r--r-- | lld/COFF/MapFile.cpp | 2 | ||||
-rw-r--r-- | lld/COFF/PDB.cpp | 2 | ||||
-rw-r--r-- | lld/COFF/Writer.cpp | 59 | ||||
-rw-r--r-- | lld/COFF/Writer.h | 6 |
4 files changed, 26 insertions, 43 deletions
diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp index b5aec6cfa90..6ca1b6647bd 100644 --- a/lld/COFF/MapFile.cpp +++ b/lld/COFF/MapFile.cpp @@ -108,7 +108,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) { // Print out file contents. for (OutputSection *Sec : OutputSections) { writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize); - OS << Sec->getName() << '\n'; + OS << Sec->Name << '\n'; for (Chunk *C : Sec->getChunks()) { auto *SC = dyn_cast<SectionChunk>(C); diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index de6aa64538b..a13b9002a98 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -1024,7 +1024,7 @@ static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod, Sym.Alignment = 12; // 2^12 = 4KB Sym.Characteristics = OS.getCharacteristics(); Sym.Length = OS.getVirtualSize(); - Sym.Name = OS.getName(); + Sym.Name = OS.Name; Sym.Rva = OS.getRVA(); Sym.SectionNumber = OS.SectionIndex; Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index b3a33ce22df..7e1e80198f2 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -218,37 +218,9 @@ static Timer DiskCommitTimer("Commit Output File", Timer::root()); void writeResult() { Writer().run(); } -void OutputSection::setRVA(uint64_t RVA) { - Header.VirtualAddress = RVA; - for (Chunk *C : Chunks) - C->setRVA(C->getRVA() + RVA); -} - -void OutputSection::setFileOffset(uint64_t Off) { - // If a section has no actual data (i.e. BSS section), we want to - // set 0 to its PointerToRawData. Otherwise the output is rejected - // by the loader. - if (Header.SizeOfRawData == 0) - return; - - // It is possible that this assignment could cause an overflow of the u32, - // but that should be caught by the FileSize check in OutputSection::run(). - Header.PointerToRawData = Off; -} - void OutputSection::addChunk(Chunk *C) { Chunks.push_back(C); C->setOutputSection(this); - uint64_t Off = Header.VirtualSize; - Off = alignTo(Off, C->Alignment); - C->setRVA(Off); - C->OutputSectionOff = Off; - Off += C->getSize(); - if (Off > UINT32_MAX) - error("section larger than 4 GiB: " + Name); - Header.VirtualSize = Off; - if (C->hasData()) - Header.SizeOfRawData = alignTo(Off, SectorSize); } void OutputSection::addPermissions(uint32_t C) { @@ -631,8 +603,7 @@ void Writer::createSymbolAndStringTable() { // Name field in the section table is 8 byte long. Longer names need // to be written to the string table. First, construct string table. for (OutputSection *Sec : OutputSections) { - StringRef Name = Sec->getName(); - if (Name.size() <= COFF::NameSize) + if (Sec->Name.size() <= COFF::NameSize) continue; // If a section isn't discardable (i.e. will be mapped at runtime), // prefer a truncated section name over a long section name in @@ -640,7 +611,7 @@ void Writer::createSymbolAndStringTable() { // always truncates, even for discardable sections. if ((Sec->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0) continue; - Sec->setStringTableOff(addEntryToStringTable(Name)); + Sec->setStringTableOff(addEntryToStringTable(Sec->Name)); } if (Config->DebugDwarf) { @@ -686,12 +657,26 @@ void Writer::assignAddresses() { return (S->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0; }); for (OutputSection *Sec : OutputSections) { - if (Sec->getName() == ".reloc") + if (Sec->Name == ".reloc") addBaserels(Sec); - Sec->setRVA(RVA); - Sec->setFileOffset(FileSize); - RVA += alignTo(Sec->getVirtualSize(), PageSize); - FileSize += alignTo(Sec->getRawSize(), SectorSize); + uint64_t RawSize = 0, VirtualSize = 0; + Sec->Header.VirtualAddress = RVA; + for (Chunk *C : Sec->getChunks()) { + VirtualSize = alignTo(VirtualSize, C->Alignment); + C->setRVA(RVA + VirtualSize); + C->OutputSectionOff = VirtualSize; + VirtualSize += C->getSize(); + if (C->hasData()) + RawSize = alignTo(VirtualSize, SectorSize); + } + if (VirtualSize > UINT32_MAX) + error("section larger than 4 GiB: " + Sec->Name); + Sec->Header.VirtualSize = VirtualSize; + Sec->Header.SizeOfRawData = RawSize; + if (RawSize != 0) + Sec->Header.PointerToRawData = FileSize; + RVA += alignTo(VirtualSize, PageSize); + FileSize += alignTo(RawSize, SectorSize); } SizeOfImage = alignTo(RVA, PageSize); } @@ -1149,7 +1134,7 @@ void Writer::sortExceptionTable() { OutputSection *Writer::findSection(StringRef Name) { for (OutputSection *Sec : OutputSections) - if (Sec->getName() == Name) + if (Sec->Name == Name) return Sec; return nullptr; } diff --git a/lld/COFF/Writer.h b/lld/COFF/Writer.h index c8e8dc86ae1..1dc1e61148b 100644 --- a/lld/COFF/Writer.h +++ b/lld/COFF/Writer.h @@ -31,10 +31,7 @@ void writeResult(); class OutputSection { public: OutputSection(llvm::StringRef N) : Name(N), Header({}) {} - void setRVA(uint64_t); - void setFileOffset(uint64_t); void addChunk(Chunk *C); - llvm::StringRef getName() { return Name; } ArrayRef<Chunk *> getChunks() { return Chunks; } void addPermissions(uint32_t C); void setPermissions(uint32_t C); @@ -61,9 +58,10 @@ public: // N.B. The section index is one based. uint32_t SectionIndex = 0; -private: llvm::StringRef Name; llvm::object::coff_section Header; + +private: uint32_t StringTableOff = 0; std::vector<Chunk *> Chunks; }; |