[lld] r196895 - [PECOFF] Refactor COFF section header creation.
Rui Ueyama
ruiu at google.com
Tue Dec 10 00:39:07 PST 2013
Author: ruiu
Date: Tue Dec 10 02:39:06 2013
New Revision: 196895
URL: http://llvm.org/viewvc/llvm-project?rev=196895&view=rev
Log:
[PECOFF] Refactor COFF section header creation.
Code to create COFF section header was scattered across many member functions
of SectionChunk. Consolidate it to a member function of SectionHeaderTableChunk.
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=196895&r1=196894&r2=196895&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Tue Dec 10 02:39:06 2013
@@ -174,6 +174,8 @@ public:
virtual void write(uint8_t *fileBuffer);
private:
+ static llvm::object::coff_section createSectionHeader(SectionChunk *chunk);
+
std::vector<SectionChunk *> _sections;
};
@@ -197,7 +199,7 @@ public:
layout->_fileOffset += fileOffset;
}
- uint64_t getSectionRva() {
+ uint64_t getVirtualAddress() {
assert(_atomLayouts.size() > 0);
return _atomLayouts[0]->_virtualAddr;
}
@@ -266,22 +268,8 @@ public:
virtual uint64_t rawSize() const { return _size; }
- // Set the file offset of the beginning of this section.
- virtual void setFileOffset(uint64_t fileOffset) {
- AtomChunk::setFileOffset(fileOffset);
- _sectionHeader.PointerToRawData = fileOffset;
- }
-
- virtual void setVirtualAddress(uint32_t rva) {
- _sectionHeader.VirtualAddress = rva;
- AtomChunk::setVirtualAddress(rva);
- }
-
- uint32_t getVirtualAddress() const { return _sectionHeader.VirtualAddress; }
- llvm::object::coff_section &getSectionHeader();
-
- ulittle32_t getSectionCharacteristics() const;
void appendAtom(const DefinedAtom *atom);
+ uint32_t getCharacteristics() const { return _characteristics; }
StringRef getSectionName() const { return _sectionName; }
static bool classof(const Chunk *c) { return c->getKind() == kindSection; }
@@ -291,12 +279,8 @@ protected:
StringRef _sectionName;
const uint32_t _characteristics;
- llvm::object::coff_section _sectionHeader;
private:
- llvm::object::coff_section
- createSectionHeader(StringRef sectionName, uint32_t characteristics) const;
-
mutable llvm::BumpPtrAllocator _alloc;
};
@@ -311,8 +295,6 @@ public:
: SectionChunk(name, getCharacteristics(ctx, name, atoms)) {
for (auto *a : atoms)
appendAtom(a);
- _sectionHeader.VirtualSize = _size;
- _sectionHeader.SizeOfRawData = size();
}
private:
@@ -612,24 +594,6 @@ void DataDirectoryChunk::write(uint8_t *
baseReloc->Size = _baseRelocSize;
}
-llvm::object::coff_section &SectionChunk::getSectionHeader() {
- if (_characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
- _sectionHeader.VirtualSize = 0;
- _sectionHeader.PointerToRawData = 0;
- } else {
- // Fix up section size before returning it. VirtualSize should be the size
- // of the actual content, and SizeOfRawData should be aligned to the section
- // alignment.
- _sectionHeader.VirtualSize = _size;
- _sectionHeader.SizeOfRawData = size();
- }
- return _sectionHeader;
-}
-
-ulittle32_t SectionChunk::getSectionCharacteristics() const {
- return _sectionHeader.Characteristics;
-}
-
void SectionChunk::appendAtom(const DefinedAtom *atom) {
// Atom may have to be at a proper alignment boundary. If so, move the
// pointer to make a room after the last atom before adding new one.
@@ -642,41 +606,12 @@ void SectionChunk::appendAtom(const Defi
}
SectionChunk::SectionChunk(StringRef sectionName, uint32_t characteristics)
- : AtomChunk(kindSection), _sectionName(sectionName), _characteristics(characteristics),
- _sectionHeader(createSectionHeader(sectionName, characteristics)) {
+ : AtomChunk(kindSection), _sectionName(sectionName),
+ _characteristics(characteristics) {
// The section should be aligned to disk sector.
_align = SECTOR_SIZE;
}
-llvm::object::coff_section
-SectionChunk::createSectionHeader(StringRef sectionName,
- uint32_t characteristics) const {
- llvm::object::coff_section header;
-
- // Section name equal to or shorter than 8 byte fits in the section
- // header. Longer names should be stored to string table, which is not
- // implemented yet.
- if (sizeof(header.Name) < sectionName.size())
- llvm_unreachable("Cannot handle section name longer than 8 byte");
-
- // Name field must be NUL-padded. If the name is exactly 8 byte long,
- // there's no terminating NUL.
- std::memset(header.Name, 0, sizeof(header.Name));
- std::strncpy(header.Name, sectionName.data(),
- std::min(sizeof(header.Name), sectionName.size()));
-
- header.VirtualSize = 0;
- header.VirtualAddress = 0;
- header.SizeOfRawData = 0;
- header.PointerToRawData = 0;
- header.PointerToRelocations = 0;
- header.PointerToLinenumbers = 0;
- header.NumberOfRelocations = 0;
- header.NumberOfLinenumbers = 0;
- header.Characteristics = characteristics;
- return header;
-}
-
void GenericSectionChunk::write(uint8_t *fileBuffer) {
if (_atomLayouts.empty())
return;
@@ -736,13 +671,49 @@ uint64_t SectionHeaderTableChunk::size()
void SectionHeaderTableChunk::write(uint8_t *fileBuffer) {
uint64_t offset = 0;
fileBuffer += fileOffset();
- for (const auto &chunk : _sections) {
- const llvm::object::coff_section &header = chunk->getSectionHeader();
+ for (SectionChunk *chunk : _sections) {
+ llvm::object::coff_section header = createSectionHeader(chunk);
std::memcpy(fileBuffer + offset, &header, sizeof(header));
offset += sizeof(header);
}
}
+llvm::object::coff_section
+SectionHeaderTableChunk::createSectionHeader(SectionChunk *chunk) {
+ llvm::object::coff_section header;
+
+ // Section name equal to or shorter than 8 byte fits in the section
+ // header. Longer names should be stored to string table, which is not
+ // implemented yet.
+ StringRef sectionName = chunk->getSectionName();
+ if (sizeof(header.Name) < sectionName.size())
+ llvm_unreachable("Cannot handle section name longer than 8 byte");
+
+ // Name field must be NUL-padded. If the name is exactly 8 byte long,
+ // there's no terminating NUL.
+ std::memset(header.Name, 0, sizeof(header.Name));
+ std::strncpy(header.Name, sectionName.data(),
+ std::min(sizeof(header.Name), sectionName.size()));
+
+ uint32_t characteristics = chunk->getCharacteristics();
+ header.VirtualAddress = chunk->getVirtualAddress();
+ header.PointerToRelocations = 0;
+ header.PointerToLinenumbers = 0;
+ header.NumberOfRelocations = 0;
+ header.NumberOfLinenumbers = 0;
+ header.SizeOfRawData = chunk->size();
+ header.Characteristics = characteristics;
+
+ if (characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
+ header.VirtualSize = 0;
+ header.PointerToRawData = 0;
+ } else {
+ header.VirtualSize = chunk->rawSize();
+ header.PointerToRawData = chunk->fileOffset();
+ }
+ return header;
+}
+
/// Creates .reloc section content from the other sections. The content of
/// .reloc is basically a list of relocation sites. The relocation sites are
/// divided into blocks. Each block represents the base relocation for a 4K
@@ -951,7 +922,7 @@ void ExecutableWriter::build(const File
baseReloc->setContents(_chunks);
if (baseReloc->size()) {
addSectionChunk(baseReloc, sectionTable);
- dataDirectory->setBaseRelocField(baseReloc->getSectionRva(),
+ dataDirectory->setBaseRelocField(baseReloc->getVirtualAddress(),
baseReloc->rawSize());
}
}
@@ -1075,7 +1046,7 @@ uint64_t ExecutableWriter::calcSectionSi
uint64_t ret = 0;
for (auto &cp : _chunks)
if (SectionChunk *chunk = dyn_cast<SectionChunk>(&*cp))
- if (chunk->getSectionCharacteristics() & sectionType)
+ if (chunk->getCharacteristics() & sectionType)
ret += chunk->size();
return ret;
}
More information about the llvm-commits
mailing list