@@ -123,6 +123,7 @@ class DOSStubChunk : public HeaderChunk {
123
123
};
124
124
125
125
// / A PEHeaderChunk represents PE header including COFF header.
126
+ template <class PEHeader >
126
127
class PEHeaderChunk : public HeaderChunk {
127
128
public:
128
129
explicit PEHeaderChunk (const PECOFFLinkingContext &ctx);
@@ -136,7 +137,7 @@ class PEHeaderChunk : public HeaderChunk {
136
137
137
138
void setSizeOfCode (uint64_t size) { _peHeader.SizeOfCode = size; }
138
139
void setBaseOfCode (uint32_t rva) { _peHeader.BaseOfCode = rva; }
139
- void setBaseOfData (uint32_t rva) { _peHeader. BaseOfData = rva; }
140
+ void setBaseOfData (uint32_t rva);
140
141
void setSizeOfImage (uint32_t size) { _peHeader.SizeOfImage = size; }
141
142
142
143
void setSizeOfInitializedData (uint64_t size) {
@@ -155,7 +156,7 @@ class PEHeaderChunk : public HeaderChunk {
155
156
156
157
private:
157
158
llvm::object::coff_file_header _coffHeader;
158
- llvm::object::pe32_header _peHeader;
159
+ PEHeader _peHeader;
159
160
};
160
161
161
162
// / A SectionHeaderTableChunk represents Section Table Header of PE/COFF
@@ -310,7 +311,8 @@ class BaseRelocChunk : public SectionChunk {
310
311
std::vector<uint8_t > _contents;
311
312
};
312
313
313
- PEHeaderChunk::PEHeaderChunk (const PECOFFLinkingContext &ctx)
314
+ template <class PEHeader >
315
+ PEHeaderChunk<PEHeader>::PEHeaderChunk(const PECOFFLinkingContext &ctx)
314
316
: HeaderChunk() {
315
317
// Set the size of the chunk and initialize the header with null bytes.
316
318
_size = sizeof (llvm::COFF::PEMagic) + sizeof (_coffHeader) + sizeof (_peHeader);
@@ -400,7 +402,18 @@ PEHeaderChunk::PEHeaderChunk(const PECOFFLinkingContext &ctx)
400
402
_peHeader.NumberOfRvaAndSize = 16 ;
401
403
}
402
404
403
- void PEHeaderChunk::write (uint8_t *buffer) {
405
+ template <>
406
+ void PEHeaderChunk<llvm::object::pe32_header>::setBaseOfData(uint32_t rva) {
407
+ _peHeader.BaseOfData = rva;
408
+ }
409
+
410
+ template <>
411
+ void PEHeaderChunk<llvm::object::pe32plus_header>::setBaseOfData(uint32_t rva) {
412
+ // BaseOfData field does not exist in PE32+ header.
413
+ }
414
+
415
+ template <class PEHeader >
416
+ void PEHeaderChunk<PEHeader>::write(uint8_t *buffer) {
404
417
std::memcpy (buffer, llvm::COFF::PEMagic, sizeof (llvm::COFF::PEMagic));
405
418
buffer += sizeof (llvm::COFF::PEMagic);
406
419
std::memcpy (buffer, &_coffHeader, sizeof (_coffHeader));
@@ -742,7 +755,7 @@ class PECOFFWriter : public Writer {
742
755
: _ctx(context), _numSections(0 ), _imageSizeInMemory(PAGE_SIZE),
743
756
_imageSizeOnDisk(0 ) {}
744
757
745
- void build (const File &linkedFile);
758
+ template < class PEHeader > void build (const File &linkedFile);
746
759
virtual error_code writeFile (const File &linkedFile, StringRef path);
747
760
748
761
private:
@@ -751,7 +764,6 @@ class PECOFFWriter : public Writer {
751
764
void addChunk (Chunk *chunk);
752
765
void addSectionChunk (SectionChunk *chunk, SectionHeaderTableChunk *table);
753
766
void setImageSizeOnDisk ();
754
- void setAddressOfEntryPoint (AtomChunk *text, PEHeaderChunk *peHeader);
755
767
uint64_t
756
768
calcSectionSize (llvm::COFF::SectionCharacteristics sectionType) const ;
757
769
@@ -829,13 +841,14 @@ void groupAtoms(const PECOFFLinkingContext &ctx, const File &file,
829
841
}
830
842
831
843
// Create all chunks that consist of the output file.
844
+ template <class PEHeader >
832
845
void PECOFFWriter::build (const File &linkedFile) {
833
846
AtomVectorMap atoms;
834
847
groupAtoms (_ctx, linkedFile, atoms);
835
848
836
849
// Create file chunks and add them to the list.
837
850
auto *dosStub = new DOSStubChunk (_ctx);
838
- auto *peHeader = new PEHeaderChunk (_ctx);
851
+ auto *peHeader = new PEHeaderChunk<PEHeader> (_ctx);
839
852
auto *dataDirectory = new DataDirectoryChunk ();
840
853
auto *sectionTable = new SectionHeaderTableChunk ();
841
854
addChunk (dosStub);
@@ -871,7 +884,19 @@ void PECOFFWriter::build(const File &linkedFile) {
871
884
continue ;
872
885
if (section->getSectionName () == " .text" ) {
873
886
peHeader->setBaseOfCode (section->getVirtualAddress ());
874
- setAddressOfEntryPoint (dyn_cast<AtomChunk>(section), peHeader);
887
+
888
+ // Find the virtual address of the entry point symbol if any. PECOFF spec
889
+ // says that entry point for dll images is optional, in which case it must
890
+ // be set to 0.
891
+ if (_ctx.entrySymbolName ().empty () && _ctx.isDll ()) {
892
+ peHeader->setAddressOfEntryPoint (0 );
893
+ } else {
894
+ uint64_t entryPointAddress =
895
+ dyn_cast<AtomChunk>(section)
896
+ ->getAtomVirtualAddress (_ctx.entrySymbolName ());
897
+ if (entryPointAddress != 0 )
898
+ peHeader->setAddressOfEntryPoint (entryPointAddress);
899
+ }
875
900
}
876
901
if (section->getSectionName () == " .data" )
877
902
peHeader->setBaseOfData (section->getVirtualAddress ());
@@ -897,7 +922,11 @@ void PECOFFWriter::build(const File &linkedFile) {
897
922
}
898
923
899
924
error_code PECOFFWriter::writeFile (const File &linkedFile, StringRef path) {
900
- this ->build (linkedFile);
925
+ if (_ctx.is64Bit ()) {
926
+ this ->build <llvm::object::pe32plus_header>(linkedFile);
927
+ } else {
928
+ this ->build <llvm::object::pe32_header>(linkedFile);
929
+ }
901
930
902
931
uint64_t totalSize = _chunks.back ()->fileOffset () + _chunks.back ()->size ();
903
932
OwningPtr<llvm::FileOutputBuffer> buffer;
@@ -977,21 +1006,6 @@ void PECOFFWriter::setImageSizeOnDisk() {
977
1006
}
978
1007
}
979
1008
980
- void PECOFFWriter::setAddressOfEntryPoint (AtomChunk *text,
981
- PEHeaderChunk *peHeader) {
982
- // Find the virtual address of the entry point symbol if any.
983
- // PECOFF spec says that entry point for dll images is optional, in which
984
- // case it must be set to 0.
985
- if (_ctx.entrySymbolName ().empty () && _ctx.isDll ()) {
986
- peHeader->setAddressOfEntryPoint (0 );
987
- } else {
988
- uint64_t entryPointAddress =
989
- text->getAtomVirtualAddress (_ctx.entrySymbolName ());
990
- if (entryPointAddress != 0 )
991
- peHeader->setAddressOfEntryPoint (entryPointAddress);
992
- }
993
- }
994
-
995
1009
uint64_t PECOFFWriter::calcSectionSize (
996
1010
llvm::COFF::SectionCharacteristics sectionType) const {
997
1011
uint64_t ret = 0 ;
0 commit comments