@@ -75,16 +75,18 @@ static void writeName(StringRef StrName, support::endian::Writer W) {
7575}
7676
7777bool XCOFFWriter::nameShouldBeInStringTable (StringRef SymbolName) {
78- return SymbolName.size () > XCOFF::NameSize;
78+ // For XCOFF64: The symbol name is always in the string table.
79+ return (SymbolName.size () > XCOFF::NameSize) || Is64Bit;
7980}
8081
8182bool XCOFFWriter::initRelocations (uint64_t &CurrentOffset) {
8283 for (uint16_t I = 0 , E = InitSections.size (); I < E; ++I) {
8384 if (!InitSections[I].Relocations .empty ()) {
8485 InitSections[I].NumberOfRelocations = InitSections[I].Relocations .size ();
8586 InitSections[I].FileOffsetToRelocations = CurrentOffset;
86- CurrentOffset += InitSections[I].NumberOfRelocations *
87- XCOFF::RelocationSerializationSize32;
87+ uint64_t RelSize = Is64Bit ? XCOFF::RelocationSerializationSize64
88+ : XCOFF::RelocationSerializationSize32;
89+ CurrentOffset += InitSections[I].NumberOfRelocations * RelSize;
8890 if (CurrentOffset > MaxRawDataSize) {
8991 ErrHandler (" maximum object size of" + Twine (MaxRawDataSize) +
9092 " exceeded when writing relocation data" );
@@ -170,9 +172,12 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
170172
171173bool XCOFFWriter::assignAddressesAndIndices () {
172174 Strings.clear ();
173- uint64_t CurrentOffset =
174- XCOFF::FileHeaderSize32 /* TODO: + auxiliaryHeaderSize() */ +
175- InitSections.size () * XCOFF::SectionHeaderSize32;
175+ uint64_t FileHdrSize =
176+ Is64Bit ? XCOFF::FileHeaderSize64 : XCOFF::FileHeaderSize32;
177+ uint64_t SecHdrSize =
178+ Is64Bit ? XCOFF::SectionHeaderSize64 : XCOFF::SectionHeaderSize32;
179+ uint64_t CurrentOffset = FileHdrSize /* TODO: + auxiliaryHeaderSize() */ +
180+ InitSections.size () * SecHdrSize;
176181
177182 // Calculate section header info.
178183 if (!initSectionHeader (CurrentOffset))
@@ -186,14 +191,25 @@ void XCOFFWriter::writeFileHeader() {
186191 W.write <uint16_t >(Obj.Header .NumberOfSections ? Obj.Header .NumberOfSections
187192 : InitFileHdr.NumberOfSections );
188193 W.write <int32_t >(Obj.Header .TimeStamp );
189- W.write <uint32_t >(Obj.Header .SymbolTableOffset
190- ? Obj.Header .SymbolTableOffset
191- : InitFileHdr.SymbolTableOffset );
192- W.write <int32_t >(Obj.Header .NumberOfSymTableEntries
193- ? Obj.Header .NumberOfSymTableEntries
194- : InitFileHdr.NumberOfSymTableEntries );
195- W.write <uint16_t >(Obj.Header .AuxHeaderSize );
196- W.write <uint16_t >(Obj.Header .Flags );
194+ if (Is64Bit) {
195+ W.write <uint64_t >(Obj.Header .SymbolTableOffset
196+ ? Obj.Header .SymbolTableOffset
197+ : InitFileHdr.SymbolTableOffset );
198+ W.write <uint16_t >(Obj.Header .AuxHeaderSize );
199+ W.write <uint16_t >(Obj.Header .Flags );
200+ W.write <int32_t >(Obj.Header .NumberOfSymTableEntries
201+ ? Obj.Header .NumberOfSymTableEntries
202+ : InitFileHdr.NumberOfSymTableEntries );
203+ } else {
204+ W.write <uint32_t >(Obj.Header .SymbolTableOffset
205+ ? Obj.Header .SymbolTableOffset
206+ : InitFileHdr.SymbolTableOffset );
207+ W.write <int32_t >(Obj.Header .NumberOfSymTableEntries
208+ ? Obj.Header .NumberOfSymTableEntries
209+ : InitFileHdr.NumberOfSymTableEntries );
210+ W.write <uint16_t >(Obj.Header .AuxHeaderSize );
211+ W.write <uint16_t >(Obj.Header .Flags );
212+ }
197213}
198214
199215void XCOFFWriter::writeSectionHeader () {
@@ -202,22 +218,40 @@ void XCOFFWriter::writeSectionHeader() {
202218 XCOFFYAML::Section DerivedSec = InitSections[I];
203219 writeName (YamlSec.SectionName , W);
204220 // Virtual address is the same as physical address.
205- uint32_t SectionAddress =
221+ uint64_t SectionAddress =
206222 YamlSec.Address ? YamlSec.Address : DerivedSec.Address ;
207- W.write <uint32_t >(SectionAddress); // Physical address
208- W.write <uint32_t >(SectionAddress); // Virtual address
209- W.write <uint32_t >(YamlSec.Size ? YamlSec.Size : DerivedSec.Size );
210- W.write <uint32_t >(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
211- : DerivedSec.FileOffsetToData );
212- W.write <uint32_t >(YamlSec.FileOffsetToRelocations
213- ? YamlSec.FileOffsetToRelocations
214- : DerivedSec.FileOffsetToRelocations );
215- W.write <uint32_t >(YamlSec.FileOffsetToLineNumbers );
216- W.write <uint16_t >(YamlSec.NumberOfRelocations
217- ? YamlSec.NumberOfRelocations
218- : DerivedSec.NumberOfRelocations );
219- W.write <uint16_t >(YamlSec.NumberOfLineNumbers );
220- W.write <int32_t >(YamlSec.Flags );
223+ if (Is64Bit) {
224+ W.write <uint64_t >(SectionAddress); // Physical address
225+ W.write <uint64_t >(SectionAddress); // Virtual address
226+ W.write <uint64_t >(YamlSec.Size ? YamlSec.Size : DerivedSec.Size );
227+ W.write <uint64_t >(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
228+ : DerivedSec.FileOffsetToData );
229+ W.write <uint64_t >(YamlSec.FileOffsetToRelocations
230+ ? YamlSec.FileOffsetToRelocations
231+ : DerivedSec.FileOffsetToRelocations );
232+ W.write <uint64_t >(YamlSec.FileOffsetToLineNumbers );
233+ W.write <uint32_t >(YamlSec.NumberOfRelocations
234+ ? YamlSec.NumberOfRelocations
235+ : DerivedSec.NumberOfRelocations );
236+ W.write <uint32_t >(YamlSec.NumberOfLineNumbers );
237+ W.write <int32_t >(YamlSec.Flags );
238+ W.OS .write_zeros (4 );
239+ } else {
240+ W.write <uint32_t >(SectionAddress); // Physical address
241+ W.write <uint32_t >(SectionAddress); // Virtual address
242+ W.write <uint32_t >(YamlSec.Size ? YamlSec.Size : DerivedSec.Size );
243+ W.write <uint32_t >(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
244+ : DerivedSec.FileOffsetToData );
245+ W.write <uint32_t >(YamlSec.FileOffsetToRelocations
246+ ? YamlSec.FileOffsetToRelocations
247+ : DerivedSec.FileOffsetToRelocations );
248+ W.write <uint32_t >(YamlSec.FileOffsetToLineNumbers );
249+ W.write <uint16_t >(YamlSec.NumberOfRelocations
250+ ? YamlSec.NumberOfRelocations
251+ : DerivedSec.NumberOfRelocations );
252+ W.write <uint16_t >(YamlSec.NumberOfLineNumbers );
253+ W.write <int32_t >(YamlSec.Flags );
254+ }
221255 }
222256}
223257
@@ -232,8 +266,7 @@ bool XCOFFWriter::writeSectionData() {
232266 ErrHandler (" redundant data was written before section data" );
233267 return false ;
234268 }
235- if (PaddingSize > 0 )
236- W.OS .write_zeros (PaddingSize);
269+ W.OS .write_zeros (PaddingSize);
237270 YamlSec.SectionData .writeAsBinary (W.OS );
238271 }
239272 }
@@ -250,10 +283,12 @@ bool XCOFFWriter::writeRelocations() {
250283 ErrHandler (" redundant data was written before relocations" );
251284 return false ;
252285 }
253- if (PaddingSize > 0 )
254- W.OS .write_zeros (PaddingSize);
286+ W.OS .write_zeros (PaddingSize);
255287 for (const XCOFFYAML::Relocation &YamlRel : YamlSec.Relocations ) {
256- W.write <uint32_t >(YamlRel.VirtualAddress );
288+ if (Is64Bit)
289+ W.write <uint64_t >(YamlRel.VirtualAddress );
290+ else
291+ W.write <uint32_t >(YamlRel.VirtualAddress );
257292 W.write <uint32_t >(YamlRel.SymbolIndex );
258293 W.write <uint8_t >(YamlRel.Info );
259294 W.write <uint8_t >(YamlRel.Type );
@@ -270,18 +305,22 @@ bool XCOFFWriter::writeSymbols() {
270305 ErrHandler (" redundant data was written before symbols" );
271306 return false ;
272307 }
273- if (PaddingSize > 0 )
274- W.OS .write_zeros (PaddingSize);
308+ W.OS .write_zeros (PaddingSize);
275309 for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols ) {
276- if (nameShouldBeInStringTable (YamlSym.SymbolName )) {
277- // For XCOFF32: A value of 0 indicates that the symbol name is in the
278- // string table.
279- W.write <int32_t >(0 );
310+ if (Is64Bit) {
311+ W.write <uint64_t >(YamlSym.Value );
280312 W.write <uint32_t >(Strings.getOffset (YamlSym.SymbolName ));
281313 } else {
282- writeName (YamlSym.SymbolName , W);
314+ if (nameShouldBeInStringTable (YamlSym.SymbolName )) {
315+ // For XCOFF32: A value of 0 indicates that the symbol name is in the
316+ // string table.
317+ W.write <int32_t >(0 );
318+ W.write <uint32_t >(Strings.getOffset (YamlSym.SymbolName ));
319+ } else {
320+ writeName (YamlSym.SymbolName , W);
321+ }
322+ W.write <uint32_t >(YamlSym.Value );
283323 }
284- W.write <uint32_t >(YamlSym.Value );
285324 W.write <int16_t >(
286325 YamlSym.SectionName .size () ? SectionIndexMap[YamlSym.SectionName ] : 0 );
287326 W.write <uint16_t >(YamlSym.Type );
@@ -295,17 +334,13 @@ bool XCOFFWriter::writeSymbols() {
295334 // length of each auxiliary entry is the same as a symbol table entry (18
296335 // bytes). The format and quantity of auxiliary entries depend on the
297336 // storage class (n_sclass) and type (n_type) of the symbol table entry.
298- W.OS .write_zeros (18 );
337+ W.OS .write_zeros (XCOFF::SymbolTableEntrySize );
299338 }
300339 }
301340 return true ;
302341}
303342
304343bool XCOFFWriter::writeXCOFF () {
305- if (Is64Bit) {
306- ErrHandler (" only XCOFF32 is currently supported" );
307- return false ;
308- }
309344 if (!assignAddressesAndIndices ())
310345 return false ;
311346 StartOffset = W.OS .tell ();
0 commit comments