forked from OSchip/llvm-project
[PECOFF][Writer] Fixed a bug that an empty section is emit to the section header.
llvm-svn: 186066
This commit is contained in:
parent
37039640e3
commit
a3635b7b3b
|
@ -400,15 +400,11 @@ public:
|
||||||
static bool classof(const Chunk *c) { return c->getKind() == kindSection; }
|
static bool classof(const Chunk *c) { return c->getKind() == kindSection; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SectionChunk(SectionHeaderTableChunk *table, StringRef sectionName,
|
SectionChunk(StringRef sectionName, uint32_t characteristics)
|
||||||
uint32_t characteristics)
|
|
||||||
: AtomChunk(kindSection),
|
: AtomChunk(kindSection),
|
||||||
_sectionHeader(createSectionHeader(sectionName, characteristics)) {
|
_sectionHeader(createSectionHeader(sectionName, characteristics)) {
|
||||||
// The section should be aligned to disk sector.
|
// The section should be aligned to disk sector.
|
||||||
_align = SECTOR_SIZE;
|
_align = SECTOR_SIZE;
|
||||||
|
|
||||||
// Add this section to the file header.
|
|
||||||
table->addSection(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildContents(const File &linkedFile,
|
void buildContents(const File &linkedFile,
|
||||||
|
@ -478,11 +474,6 @@ void SectionHeaderTableChunk::write(uint8_t *fileBuffer) {
|
||||||
uint64_t offset = 0;
|
uint64_t offset = 0;
|
||||||
fileBuffer += fileOffset();
|
fileBuffer += fileOffset();
|
||||||
for (const auto &chunk : _sections) {
|
for (const auto &chunk : _sections) {
|
||||||
// Skip the empty section. Windows loader does not like a section
|
|
||||||
// of size zero and rejects such executable.
|
|
||||||
if (chunk->size() == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const llvm::object::coff_section &header = chunk->getSectionHeader();
|
const llvm::object::coff_section &header = chunk->getSectionHeader();
|
||||||
std::memcpy(fileBuffer + offset, &header, sizeof(header));
|
std::memcpy(fileBuffer + offset, &header, sizeof(header));
|
||||||
offset += sizeof(header);
|
offset += sizeof(header);
|
||||||
|
@ -492,8 +483,8 @@ void SectionHeaderTableChunk::write(uint8_t *fileBuffer) {
|
||||||
// \brief A TextSectionChunk represents a .text section.
|
// \brief A TextSectionChunk represents a .text section.
|
||||||
class TextSectionChunk : public SectionChunk {
|
class TextSectionChunk : public SectionChunk {
|
||||||
public:
|
public:
|
||||||
TextSectionChunk(const File &linkedFile, SectionHeaderTableChunk *table)
|
TextSectionChunk(const File &linkedFile)
|
||||||
: SectionChunk(table, ".text", characteristics) {
|
: SectionChunk(".text", characteristics) {
|
||||||
buildContents(linkedFile, [](const DefinedAtom *atom) {
|
buildContents(linkedFile, [](const DefinedAtom *atom) {
|
||||||
return atom->contentType() == DefinedAtom::typeCode;
|
return atom->contentType() == DefinedAtom::typeCode;
|
||||||
});
|
});
|
||||||
|
@ -509,8 +500,8 @@ private:
|
||||||
// \brief A RDataSectionChunk represents a .rdata section.
|
// \brief A RDataSectionChunk represents a .rdata section.
|
||||||
class RDataSectionChunk : public SectionChunk {
|
class RDataSectionChunk : public SectionChunk {
|
||||||
public:
|
public:
|
||||||
RDataSectionChunk(const File &linkedFile, SectionHeaderTableChunk *table)
|
RDataSectionChunk(const File &linkedFile)
|
||||||
: SectionChunk(table, ".rdata", characteristics) {
|
: SectionChunk(".rdata", characteristics) {
|
||||||
buildContents(linkedFile, [](const DefinedAtom *atom) {
|
buildContents(linkedFile, [](const DefinedAtom *atom) {
|
||||||
return (atom->contentType() == DefinedAtom::typeData &&
|
return (atom->contentType() == DefinedAtom::typeData &&
|
||||||
atom->permissions() == DefinedAtom::permR__);
|
atom->permissions() == DefinedAtom::permR__);
|
||||||
|
@ -527,8 +518,8 @@ private:
|
||||||
// \brief A DataSectionChunk represents a .data section.
|
// \brief A DataSectionChunk represents a .data section.
|
||||||
class DataSectionChunk : public SectionChunk {
|
class DataSectionChunk : public SectionChunk {
|
||||||
public:
|
public:
|
||||||
DataSectionChunk(const File &linkedFile, SectionHeaderTableChunk *table)
|
DataSectionChunk(const File &linkedFile)
|
||||||
: SectionChunk(table, ".data", characteristics) {
|
: SectionChunk(".data", characteristics) {
|
||||||
buildContents(linkedFile, [](const DefinedAtom *atom) {
|
buildContents(linkedFile, [](const DefinedAtom *atom) {
|
||||||
return (atom->contentType() == DefinedAtom::typeData &&
|
return (atom->contentType() == DefinedAtom::typeData &&
|
||||||
atom->permissions() == DefinedAtom::permRW_);
|
atom->permissions() == DefinedAtom::permRW_);
|
||||||
|
@ -569,20 +560,21 @@ private:
|
||||||
chunk->align());
|
chunk->align());
|
||||||
chunk->setFileOffset(_imageSizeOnDisk);
|
chunk->setFileOffset(_imageSizeOnDisk);
|
||||||
_imageSizeOnDisk += chunk->size();
|
_imageSizeOnDisk += chunk->size();
|
||||||
|
}
|
||||||
|
|
||||||
// Compute and set the starting address of sections when loaded in
|
void maybeAddSectionChunk(SectionChunk *chunk,
|
||||||
// memory. They are different from positions on disk because sections need
|
SectionHeaderTableChunk *table) {
|
||||||
// to be sector-aligned on disk but page-aligned in memory.
|
// Skip the empty section. Windows loader does not like a section of size
|
||||||
if (SectionChunk *sectionChunk = dyn_cast<SectionChunk>(chunk)) {
|
// zero and rejects such executable.
|
||||||
sectionChunk->setVirtualAddress(_imageSizeInMemory);
|
|
||||||
// Skip the empty section.
|
|
||||||
if (chunk->size() == 0)
|
if (chunk->size() == 0)
|
||||||
return;
|
return;
|
||||||
|
addChunk(chunk);
|
||||||
|
table->addSection(chunk);
|
||||||
_numSections++;
|
_numSections++;
|
||||||
|
chunk->setVirtualAddress(_imageSizeInMemory);
|
||||||
_imageSizeInMemory = llvm::RoundUpToAlignment(
|
_imageSizeInMemory = llvm::RoundUpToAlignment(
|
||||||
_imageSizeInMemory + chunk->size(), PAGE_SIZE);
|
_imageSizeInMemory + chunk->size(), PAGE_SIZE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ExecutableWriter(const PECOFFTargetInfo &targetInfo)
|
explicit ExecutableWriter(const PECOFFTargetInfo &targetInfo)
|
||||||
|
@ -596,23 +588,29 @@ public:
|
||||||
auto *peHeader = new PEHeaderChunk(_PECOFFTargetInfo);
|
auto *peHeader = new PEHeaderChunk(_PECOFFTargetInfo);
|
||||||
auto *dataDirectory = new DataDirectoryChunk();
|
auto *dataDirectory = new DataDirectoryChunk();
|
||||||
auto *sectionTable = new SectionHeaderTableChunk();
|
auto *sectionTable = new SectionHeaderTableChunk();
|
||||||
auto *text = new TextSectionChunk(linkedFile, sectionTable);
|
auto *text = new TextSectionChunk(linkedFile);
|
||||||
auto *rdata = new RDataSectionChunk(linkedFile, sectionTable);
|
auto *rdata = new RDataSectionChunk(linkedFile);
|
||||||
auto *data = new DataSectionChunk(linkedFile, sectionTable);
|
auto *data = new DataSectionChunk(linkedFile);
|
||||||
|
|
||||||
addChunk(dosStub);
|
addChunk(dosStub);
|
||||||
addChunk(peHeader);
|
addChunk(peHeader);
|
||||||
addChunk(dataDirectory);
|
addChunk(dataDirectory);
|
||||||
addChunk(sectionTable);
|
addChunk(sectionTable);
|
||||||
addChunk(text);
|
maybeAddSectionChunk(text, sectionTable);
|
||||||
addChunk(rdata);
|
maybeAddSectionChunk(rdata, sectionTable);
|
||||||
addChunk(data);
|
maybeAddSectionChunk(data, sectionTable);
|
||||||
|
|
||||||
// Now that we know the size and file offset of sections. Set the file
|
// Now that we know the size and file offset of sections. Set the file
|
||||||
// header accordingly.
|
// header accordingly.
|
||||||
peHeader->setSizeOfCode(text->size());
|
peHeader->setSizeOfCode(text->size());
|
||||||
|
if (text->size() > 0) {
|
||||||
peHeader->setBaseOfCode(text->getVirtualAddress());
|
peHeader->setBaseOfCode(text->getVirtualAddress());
|
||||||
|
}
|
||||||
|
if (rdata->size() > 0) {
|
||||||
peHeader->setBaseOfData(rdata->getVirtualAddress());
|
peHeader->setBaseOfData(rdata->getVirtualAddress());
|
||||||
|
} else if (data->size() > 0) {
|
||||||
|
peHeader->setBaseOfData(data->getVirtualAddress());
|
||||||
|
}
|
||||||
peHeader->setSizeOfInitializedData(rdata->size() + data->size());
|
peHeader->setSizeOfInitializedData(rdata->size() + data->size());
|
||||||
peHeader->setNumberOfSections(_numSections);
|
peHeader->setNumberOfSections(_numSections);
|
||||||
peHeader->setSizeOfImage(_imageSizeInMemory);
|
peHeader->setSizeOfImage(_imageSizeInMemory);
|
||||||
|
|
|
@ -34,7 +34,7 @@ FILE: SizeOfInitializedData: 0
|
||||||
FILE: SizeOfUninitializedData: 0
|
FILE: SizeOfUninitializedData: 0
|
||||||
FILE: AddressOfEntryPoint: 0x1000
|
FILE: AddressOfEntryPoint: 0x1000
|
||||||
FILE: BaseOfCode: 0x1000
|
FILE: BaseOfCode: 0x1000
|
||||||
FILE: BaseOfData: 0x2000
|
FILE: BaseOfData: 0
|
||||||
FILE: ImageBase: 0x400000
|
FILE: ImageBase: 0x400000
|
||||||
FILE: SectionAlignment: 4096
|
FILE: SectionAlignment: 4096
|
||||||
FILE: FileAlignment: 512
|
FILE: FileAlignment: 512
|
||||||
|
|
Loading…
Reference in New Issue