@@ -75,16 +75,18 @@ static void writeName(StringRef StrName, support::endian::Writer W) {
75
75
}
76
76
77
77
bool 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;
79
80
}
80
81
81
82
bool XCOFFWriter::initRelocations (uint64_t &CurrentOffset) {
82
83
for (uint16_t I = 0 , E = InitSections.size (); I < E; ++I) {
83
84
if (!InitSections[I].Relocations .empty ()) {
84
85
InitSections[I].NumberOfRelocations = InitSections[I].Relocations .size ();
85
86
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;
88
90
if (CurrentOffset > MaxRawDataSize) {
89
91
ErrHandler (" maximum object size of" + Twine (MaxRawDataSize) +
90
92
" exceeded when writing relocation data" );
@@ -170,9 +172,12 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
170
172
171
173
bool XCOFFWriter::assignAddressesAndIndices () {
172
174
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;
176
181
177
182
// Calculate section header info.
178
183
if (!initSectionHeader (CurrentOffset))
@@ -186,14 +191,25 @@ void XCOFFWriter::writeFileHeader() {
186
191
W.write <uint16_t >(Obj.Header .NumberOfSections ? Obj.Header .NumberOfSections
187
192
: InitFileHdr.NumberOfSections );
188
193
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
+ }
197
213
}
198
214
199
215
void XCOFFWriter::writeSectionHeader () {
@@ -202,22 +218,40 @@ void XCOFFWriter::writeSectionHeader() {
202
218
XCOFFYAML::Section DerivedSec = InitSections[I];
203
219
writeName (YamlSec.SectionName , W);
204
220
// Virtual address is the same as physical address.
205
- uint32_t SectionAddress =
221
+ uint64_t SectionAddress =
206
222
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
+ }
221
255
}
222
256
}
223
257
@@ -232,8 +266,7 @@ bool XCOFFWriter::writeSectionData() {
232
266
ErrHandler (" redundant data was written before section data" );
233
267
return false ;
234
268
}
235
- if (PaddingSize > 0 )
236
- W.OS .write_zeros (PaddingSize);
269
+ W.OS .write_zeros (PaddingSize);
237
270
YamlSec.SectionData .writeAsBinary (W.OS );
238
271
}
239
272
}
@@ -250,10 +283,12 @@ bool XCOFFWriter::writeRelocations() {
250
283
ErrHandler (" redundant data was written before relocations" );
251
284
return false ;
252
285
}
253
- if (PaddingSize > 0 )
254
- W.OS .write_zeros (PaddingSize);
286
+ W.OS .write_zeros (PaddingSize);
255
287
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 );
257
292
W.write <uint32_t >(YamlRel.SymbolIndex );
258
293
W.write <uint8_t >(YamlRel.Info );
259
294
W.write <uint8_t >(YamlRel.Type );
@@ -270,18 +305,22 @@ bool XCOFFWriter::writeSymbols() {
270
305
ErrHandler (" redundant data was written before symbols" );
271
306
return false ;
272
307
}
273
- if (PaddingSize > 0 )
274
- W.OS .write_zeros (PaddingSize);
308
+ W.OS .write_zeros (PaddingSize);
275
309
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 );
280
312
W.write <uint32_t >(Strings.getOffset (YamlSym.SymbolName ));
281
313
} 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 );
283
323
}
284
- W.write <uint32_t >(YamlSym.Value );
285
324
W.write <int16_t >(
286
325
YamlSym.SectionName .size () ? SectionIndexMap[YamlSym.SectionName ] : 0 );
287
326
W.write <uint16_t >(YamlSym.Type );
@@ -295,17 +334,13 @@ bool XCOFFWriter::writeSymbols() {
295
334
// length of each auxiliary entry is the same as a symbol table entry (18
296
335
// bytes). The format and quantity of auxiliary entries depend on the
297
336
// 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 );
299
338
}
300
339
}
301
340
return true ;
302
341
}
303
342
304
343
bool XCOFFWriter::writeXCOFF () {
305
- if (Is64Bit) {
306
- ErrHandler (" only XCOFF32 is currently supported" );
307
- return false ;
308
- }
309
344
if (!assignAddressesAndIndices ())
310
345
return false ;
311
346
StartOffset = W.OS .tell ();
0 commit comments