llvm.org GIT mirror llvm / 50c1eff
yaml2obj: Support bigobj Teach yaml2obj how to make a bigobj COFF file. Like the rest of LLVM, we automatically decide whether or not to use regular COFF or bigobj COFF on the fly depending on how many sections the resulting object would have. This ends the task of adding bigobj support to LLVM. N.B. This was tested by forcing yaml2obj to be used in bigobj mode regardless of the number of sections. While a dedicated test was written, the smallest I could make it was 36 MB (!) of yaml and it still took a significant amount of time to execute on a powerful machine. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217858 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 5 years ago
4 changed file(s) with 78 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
6262 };
6363
6464 struct BigObjHeader {
65 enum { MinBigObjectVersion = 2 };
65 enum : uint16_t { MinBigObjectVersion = 2 };
6666
6767 uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
6868 uint16_t Sig2; ///< Must be 0xFFFF.
55 - !Symbol
66 Name: .file
77 Value: 0
8 SectionNumber: 65534
8 SectionNumber: -2
99 SimpleType: IMAGE_SYM_TYPE_NULL
1010 ComplexType: IMAGE_SYM_DTYPE_NULL
1111 StorageClass: IMAGE_SYM_CLASS_FILE
1313 - !Symbol
1414 Name: '@comp.id'
1515 Value: 13485607
16 SectionNumber: 65535
16 SectionNumber: -1
1717 SimpleType: IMAGE_SYM_TYPE_NULL
1818 ComplexType: IMAGE_SYM_DTYPE_NULL
1919 StorageClass: IMAGE_SYM_CLASS_STATIC
55 - !Symbol
66 Name: .file
77 Value: 0
8 SectionNumber: 65534
8 SectionNumber: -2
99 SimpleType: IMAGE_SYM_TYPE_NULL
1010 ComplexType: IMAGE_SYM_DTYPE_NULL
1111 StorageClass: IMAGE_SYM_CLASS_FILE
1313 - !Symbol
1414 Name: '@comp.id'
1515 Value: 13485607
16 SectionNumber: 65535
16 SectionNumber: -1
1717 SimpleType: IMAGE_SYM_TYPE_NULL
1818 ComplexType: IMAGE_SYM_DTYPE_NULL
1919 StorageClass: IMAGE_SYM_CLASS_STATIC
3535 StringTable.append(4, char(0));
3636 }
3737
38 bool useBigObj() const {
39 return Obj.Sections.size() > COFF::MaxNumberOfSections16;
40 }
41
42 unsigned getHeaderSize() const {
43 return useBigObj() ? COFF::Header32Size : COFF::Header16Size;
44 }
45
46 unsigned getSymbolSize() const {
47 return useBigObj() ? COFF::Symbol32Size : COFF::Symbol16Size;
48 }
49
3850 bool parseSections() {
3951 for (std::vector::iterator i = Obj.Sections.begin(),
4052 e = Obj.Sections.end(); i != e; ++i) {
120132
121133 // The section table starts immediately after the header, including the
122134 // optional header.
123 SectionTableStart = COFF::Header16Size + CP.Obj.Header.SizeOfOptionalHeader;
135 SectionTableStart = CP.getHeaderSize() + CP.Obj.Header.SizeOfOptionalHeader;
124136 SectionTableSize = COFF::SectionSize * CP.Obj.Sections.size();
125137
126138 uint32_t CurrentSectionDataOffset = SectionTableStart + SectionTableSize;
162174 NumberOfAuxSymbols += 1;
163175 if (!i->File.empty())
164176 NumberOfAuxSymbols +=
165 (i->File.size() + COFF::Symbol16Size - 1) / COFF::Symbol16Size;
177 (i->File.size() + CP.getSymbolSize() - 1) / CP.getSymbolSize();
166178 if (i->SectionDefinition)
167179 NumberOfAuxSymbols += 1;
168180 if (i->CLRToken)
221233 return zeros_impl();
222234 }
223235
236 struct num_zeros_impl {
237 size_t N;
238 num_zeros_impl(size_t N) : N(N) {}
239 };
240
241 raw_ostream &operator<<(raw_ostream &OS, const num_zeros_impl &NZI) {
242 for (size_t I = 0; I != NZI.N; ++I)
243 OS.write(0);
244 return OS;
245 }
246
247 num_zeros_impl num_zeros(size_t N) {
248 num_zeros_impl NZI(N);
249 return NZI;
250 }
251
224252 bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
225 OS << binary_le(CP.Obj.Header.Machine)
226 << binary_le(static_cast(CP.Obj.Header.NumberOfSections))
227 << binary_le(CP.Obj.Header.TimeDateStamp)
228 << binary_le(CP.Obj.Header.PointerToSymbolTable)
229 << binary_le(CP.Obj.Header.NumberOfSymbols)
230 << binary_le(CP.Obj.Header.SizeOfOptionalHeader)
231 << binary_le(CP.Obj.Header.Characteristics);
253 if (CP.useBigObj()) {
254 OS << binary_le(static_cast(COFF::IMAGE_FILE_MACHINE_UNKNOWN))
255 << binary_le(static_cast(0xffff))
256 << binary_le(static_cast(COFF::BigObjHeader::MinBigObjectVersion))
257 << binary_le(CP.Obj.Header.Machine)
258 << binary_le(CP.Obj.Header.TimeDateStamp);
259 OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic));
260 OS << zeros(uint32_t(0))
261 << zeros(uint32_t(0))
262 << zeros(uint32_t(0))
263 << zeros(uint32_t(0))
264 << binary_le(CP.Obj.Header.NumberOfSections)
265 << binary_le(CP.Obj.Header.PointerToSymbolTable)
266 << binary_le(CP.Obj.Header.NumberOfSymbols);
267 } else {
268 OS << binary_le(CP.Obj.Header.Machine)
269 << binary_le(static_cast(CP.Obj.Header.NumberOfSections))
270 << binary_le(CP.Obj.Header.TimeDateStamp)
271 << binary_le(CP.Obj.Header.PointerToSymbolTable)
272 << binary_le(CP.Obj.Header.NumberOfSymbols)
273 << binary_le(CP.Obj.Header.SizeOfOptionalHeader)
274 << binary_le(CP.Obj.Header.Characteristics);
275 }
232276
233277 // Output section table.
234278 for (std::vector::iterator i = CP.Obj.Sections.begin(),
275319 e = CP.Obj.Symbols.end();
276320 i != e; ++i) {
277321 OS.write(i->Header.Name, COFF::NameSize);
278 OS << binary_le(i->Header.Value)
279 << binary_le(static_cast(i->Header.SectionNumber))
280 << binary_le(i->Header.Type)
322 OS << binary_le(i->Header.Value);
323 if (CP.useBigObj())
324 OS << binary_le(i->Header.SectionNumber);
325 else
326 OS << binary_le(static_cast(i->Header.SectionNumber));
327 OS << binary_le(i->Header.Type)
281328 << binary_le(i->Header.StorageClass)
282329 << binary_le(i->Header.NumberOfAuxSymbols);
283330
286333 << binary_le(i->FunctionDefinition->TotalSize)
287334 << binary_le(i->FunctionDefinition->PointerToLinenumber)
288335 << binary_le(i->FunctionDefinition->PointerToNextFunction)
289 << zeros(i->FunctionDefinition->unused);
336 << zeros(i->FunctionDefinition->unused)
337 << num_zeros(CP.getSymbolSize() - COFF::Symbol16Size);
290338 if (i->bfAndefSymbol)
291339 OS << zeros(i->bfAndefSymbol->unused1)
292340 << binary_le(i->bfAndefSymbol->Linenumber)
293341 << zeros(i->bfAndefSymbol->unused2)
294342 << binary_le(i->bfAndefSymbol->PointerToNextFunction)
295 << zeros(i->bfAndefSymbol->unused3);
343 << zeros(i->bfAndefSymbol->unused3)
344 << num_zeros(CP.getSymbolSize() - COFF::Symbol16Size);
296345 if (i->WeakExternal)
297346 OS << binary_le(i->WeakExternal->TagIndex)
298347 << binary_le(i->WeakExternal->Characteristics)
299 << zeros(i->WeakExternal->unused);
348 << zeros(i->WeakExternal->unused)
349 << num_zeros(CP.getSymbolSize() - COFF::Symbol16Size);
300350 if (!i->File.empty()) {
351 unsigned SymbolSize = CP.getSymbolSize();
301352 uint32_t NumberOfAuxRecords =
302 (i->File.size() + COFF::Symbol16Size - 1) / COFF::Symbol16Size;
303 uint32_t NumberOfAuxBytes = NumberOfAuxRecords * COFF::Symbol16Size;
353 (i->File.size() + SymbolSize - 1) / SymbolSize;
354 uint32_t NumberOfAuxBytes = NumberOfAuxRecords * SymbolSize;
304355 uint32_t NumZeros = NumberOfAuxBytes - i->File.size();
305356 OS.write(i->File.data(), i->File.size());
306 for (uint32_t Padding = 0; Padding < NumZeros; ++Padding)
307 OS.write(0);
357 OS << num_zeros(NumZeros);
308358 }
309359 if (i->SectionDefinition)
310360 OS << binary_le(i->SectionDefinition->Length)
314364 << binary_le(static_cast(i->SectionDefinition->Number))
315365 << binary_le(i->SectionDefinition->Selection)
316366 << zeros(i->SectionDefinition->unused)
317 << binary_le(static_cast(i->SectionDefinition->Number >> 16));
367 << binary_le(static_cast(i->SectionDefinition->Number >> 16))
368 << num_zeros(CP.getSymbolSize() - COFF::Symbol16Size);
318369 if (i->CLRToken)
319370 OS << binary_le(i->CLRToken->AuxType)
320371 << zeros(i->CLRToken->unused1)
321372 << binary_le(i->CLRToken->SymbolTableIndex)
322 << zeros(i->CLRToken->unused2);
373 << zeros(i->CLRToken->unused2)
374 << num_zeros(CP.getSymbolSize() - COFF::Symbol16Size);
323375 }
324376
325377 // Output string table.