1 //===-- llvm/MC/WinCOFFObjectWriter.cpp -------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains an implementation of a Win32 COFF object file writer.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/MC/MCWinCOFFObjectWriter.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringMap.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/MC/MCAsmLayout.h"
21 #include "llvm/MC/MCAssembler.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCObjectWriter.h"
25 #include "llvm/MC/MCSection.h"
26 #include "llvm/MC/MCSectionCOFF.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCValue.h"
29 #include "llvm/MC/StringTableBuilder.h"
30 #include "llvm/Support/COFF.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/Endian.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/TimeValue.h"
39 #define DEBUG_TYPE "WinCOFFObjectWriter"
42 typedef SmallString
<COFF::NameSize
> name
;
53 AuxiliaryType AuxType
;
64 typedef SmallVector
<AuxSymbol
, 1> AuxiliarySymbols
;
73 MCSymbolData
const *MCData
;
75 COFFSymbol(StringRef name
);
76 void set_name_offset(uint32_t Offset
);
78 bool should_keep() const;
81 // This class contains staging data for a COFF relocation entry.
82 struct COFFRelocation
{
83 COFF::relocation Data
;
86 COFFRelocation() : Symb(nullptr) {}
87 static size_t size() { return COFF::RelocationSize
; }
90 typedef std::vector
<COFFRelocation
> relocations
;
98 MCSectionData
const *MCData
;
100 relocations Relocations
;
102 COFFSection(StringRef name
);
103 static size_t size();
106 class WinCOFFObjectWriter
: public MCObjectWriter
{
109 typedef std::vector
<std::unique_ptr
<COFFSymbol
>> symbols
;
110 typedef std::vector
<std::unique_ptr
<COFFSection
>> sections
;
112 typedef DenseMap
<MCSymbol
const *, COFFSymbol
*> symbol_map
;
113 typedef DenseMap
<MCSection
const *, COFFSection
*> section_map
;
115 std::unique_ptr
<MCWinCOFFObjectTargetWriter
> TargetObjectWriter
;
117 // Root level file contents.
121 StringTableBuilder Strings
;
123 // Maps used during object file creation.
124 section_map SectionMap
;
125 symbol_map SymbolMap
;
129 WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter
*MOTW
, raw_ostream
&OS
);
131 void reset() override
{
132 memset(&Header
, 0, sizeof(Header
));
133 Header
.Machine
= TargetObjectWriter
->getMachine();
139 MCObjectWriter::reset();
142 COFFSymbol
*createSymbol(StringRef Name
);
143 COFFSymbol
*GetOrCreateCOFFSymbol(const MCSymbol
* Symbol
);
144 COFFSection
*createSection(StringRef Name
);
146 template <typename object_t
, typename list_t
>
147 object_t
*createCOFFEntity(StringRef Name
, list_t
&List
);
149 void DefineSection(MCSectionData
const &SectionData
);
150 void DefineSymbol(MCSymbolData
const &SymbolData
, MCAssembler
&Assembler
,
151 const MCAsmLayout
&Layout
);
153 void SetSymbolName(COFFSymbol
&S
);
154 void SetSectionName(COFFSection
&S
);
156 bool ExportSymbol(const MCSymbol
&Symbol
, MCAssembler
&Asm
);
158 bool IsPhysicalSection(COFFSection
*S
);
160 // Entity writing methods.
162 void WriteFileHeader(const COFF::header
&Header
);
163 void WriteSymbol(const COFFSymbol
&S
);
164 void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols
&S
);
165 void WriteSectionHeader(const COFF::section
&S
);
166 void WriteRelocation(const COFF::relocation
&R
);
168 // MCObjectWriter interface implementation.
170 void ExecutePostLayoutBinding(MCAssembler
&Asm
,
171 const MCAsmLayout
&Layout
) override
;
173 bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler
&Asm
,
174 const MCSymbolData
&DataA
,
175 const MCFragment
&FB
, bool InSet
,
176 bool IsPCRel
) const override
;
178 void RecordRelocation(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
179 const MCFragment
*Fragment
, const MCFixup
&Fixup
,
180 MCValue Target
, bool &IsPCRel
,
181 uint64_t &FixedValue
) override
;
183 void WriteObject(MCAssembler
&Asm
, const MCAsmLayout
&Layout
) override
;
187 static inline void write_uint32_le(void *Data
, uint32_t Value
) {
188 support::endian::write
<uint32_t, support::little
, support::unaligned
>(Data
,
192 //------------------------------------------------------------------------------
193 // Symbol class implementation
195 COFFSymbol::COFFSymbol(StringRef name
)
196 : Name(name
.begin(), name
.end())
201 memset(&Data
, 0, sizeof(Data
));
204 // In the case that the name does not fit within 8 bytes, the offset
205 // into the string table is stored in the last 4 bytes instead, leaving
206 // the first 4 bytes as 0.
207 void COFFSymbol::set_name_offset(uint32_t Offset
) {
208 write_uint32_le(Data
.Name
+ 0, 0);
209 write_uint32_le(Data
.Name
+ 4, Offset
);
212 /// logic to decide if the symbol should be reported in the symbol table
213 bool COFFSymbol::should_keep() const {
214 // no section means its external, keep it
218 // if it has relocations pointing at it, keep it
219 if (Relocations
> 0) {
220 assert(Section
->Number
!= -1 && "Sections with relocations must be real!");
224 // if the section its in is being droped, drop it
225 if (Section
->Number
== -1)
228 // if it is the section symbol, keep it
229 if (Section
->Symbol
== this)
232 // if its temporary, drop it
233 if (MCData
&& MCData
->getSymbol().isTemporary())
236 // otherwise, keep it
240 //------------------------------------------------------------------------------
241 // Section class implementation
243 COFFSection::COFFSection(StringRef name
)
247 memset(&Header
, 0, sizeof(Header
));
250 size_t COFFSection::size() {
251 return COFF::SectionSize
;
254 //------------------------------------------------------------------------------
255 // WinCOFFObjectWriter class implementation
257 WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter
*MOTW
,
259 : MCObjectWriter(OS
, true), TargetObjectWriter(MOTW
) {
260 memset(&Header
, 0, sizeof(Header
));
262 Header
.Machine
= TargetObjectWriter
->getMachine();
265 COFFSymbol
*WinCOFFObjectWriter::createSymbol(StringRef Name
) {
266 return createCOFFEntity
<COFFSymbol
>(Name
, Symbols
);
269 COFFSymbol
*WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol
*Symbol
) {
270 symbol_map::iterator i
= SymbolMap
.find(Symbol
);
271 if (i
!= SymbolMap
.end())
273 COFFSymbol
*RetSymbol
=
274 createCOFFEntity
<COFFSymbol
>(Symbol
->getName(), Symbols
);
275 SymbolMap
[Symbol
] = RetSymbol
;
279 COFFSection
*WinCOFFObjectWriter::createSection(StringRef Name
) {
280 return createCOFFEntity
<COFFSection
>(Name
, Sections
);
283 /// A template used to lookup or create a symbol/section, and initialize it if
285 template <typename object_t
, typename list_t
>
286 object_t
*WinCOFFObjectWriter::createCOFFEntity(StringRef Name
,
288 List
.push_back(make_unique
<object_t
>(Name
));
290 return List
.back().get();
293 /// This function takes a section data object from the assembler
294 /// and creates the associated COFF section staging object.
295 void WinCOFFObjectWriter::DefineSection(MCSectionData
const &SectionData
) {
296 assert(SectionData
.getSection().getVariant() == MCSection::SV_COFF
297 && "Got non-COFF section in the COFF backend!");
298 // FIXME: Not sure how to verify this (at least in a debug build).
299 MCSectionCOFF
const &Sec
=
300 static_cast<MCSectionCOFF
const &>(SectionData
.getSection());
302 COFFSection
*coff_section
= createSection(Sec
.getSectionName());
303 COFFSymbol
*coff_symbol
= createSymbol(Sec
.getSectionName());
304 if (Sec
.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE
) {
305 if (const MCSymbol
*S
= Sec
.getCOMDATSymbol()) {
306 COFFSymbol
*COMDATSymbol
= GetOrCreateCOFFSymbol(S
);
307 if (COMDATSymbol
->Section
)
308 report_fatal_error("two sections have the same comdat");
309 COMDATSymbol
->Section
= coff_section
;
313 coff_section
->Symbol
= coff_symbol
;
314 coff_symbol
->Section
= coff_section
;
315 coff_symbol
->Data
.StorageClass
= COFF::IMAGE_SYM_CLASS_STATIC
;
317 // In this case the auxiliary symbol is a Section Definition.
318 coff_symbol
->Aux
.resize(1);
319 memset(&coff_symbol
->Aux
[0], 0, sizeof(coff_symbol
->Aux
[0]));
320 coff_symbol
->Aux
[0].AuxType
= ATSectionDefinition
;
321 coff_symbol
->Aux
[0].Aux
.SectionDefinition
.Selection
= Sec
.getSelection();
323 coff_section
->Header
.Characteristics
= Sec
.getCharacteristics();
325 uint32_t &Characteristics
= coff_section
->Header
.Characteristics
;
326 switch (SectionData
.getAlignment()) {
327 case 1: Characteristics
|= COFF::IMAGE_SCN_ALIGN_1BYTES
; break;
328 case 2: Characteristics
|= COFF::IMAGE_SCN_ALIGN_2BYTES
; break;
329 case 4: Characteristics
|= COFF::IMAGE_SCN_ALIGN_4BYTES
; break;
330 case 8: Characteristics
|= COFF::IMAGE_SCN_ALIGN_8BYTES
; break;
331 case 16: Characteristics
|= COFF::IMAGE_SCN_ALIGN_16BYTES
; break;
332 case 32: Characteristics
|= COFF::IMAGE_SCN_ALIGN_32BYTES
; break;
333 case 64: Characteristics
|= COFF::IMAGE_SCN_ALIGN_64BYTES
; break;
334 case 128: Characteristics
|= COFF::IMAGE_SCN_ALIGN_128BYTES
; break;
335 case 256: Characteristics
|= COFF::IMAGE_SCN_ALIGN_256BYTES
; break;
336 case 512: Characteristics
|= COFF::IMAGE_SCN_ALIGN_512BYTES
; break;
337 case 1024: Characteristics
|= COFF::IMAGE_SCN_ALIGN_1024BYTES
; break;
338 case 2048: Characteristics
|= COFF::IMAGE_SCN_ALIGN_2048BYTES
; break;
339 case 4096: Characteristics
|= COFF::IMAGE_SCN_ALIGN_4096BYTES
; break;
340 case 8192: Characteristics
|= COFF::IMAGE_SCN_ALIGN_8192BYTES
; break;
342 llvm_unreachable("unsupported section alignment");
345 // Bind internal COFF section to MC section.
346 coff_section
->MCData
= &SectionData
;
347 SectionMap
[&SectionData
.getSection()] = coff_section
;
350 static uint64_t getSymbolValue(const MCSymbolData
&Data
,
351 const MCAsmLayout
&Layout
) {
352 if (Data
.isCommon() && Data
.isExternal())
353 return Data
.getCommonSize();
356 if (!Layout
.getSymbolOffset(&Data
, Res
))
362 /// This function takes a symbol data object from the assembler
363 /// and creates the associated COFF symbol staging object.
364 void WinCOFFObjectWriter::DefineSymbol(MCSymbolData
const &SymbolData
,
365 MCAssembler
&Assembler
,
366 const MCAsmLayout
&Layout
) {
367 MCSymbol
const &Symbol
= SymbolData
.getSymbol();
368 COFFSymbol
*coff_symbol
= GetOrCreateCOFFSymbol(&Symbol
);
369 SymbolMap
[&Symbol
] = coff_symbol
;
371 if (SymbolData
.getFlags() & COFF::SF_WeakExternal
) {
372 coff_symbol
->Data
.StorageClass
= COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
;
374 if (Symbol
.isVariable()) {
375 const MCSymbolRefExpr
*SymRef
=
376 dyn_cast
<MCSymbolRefExpr
>(Symbol
.getVariableValue());
379 report_fatal_error("Weak externals may only alias symbols");
381 coff_symbol
->Other
= GetOrCreateCOFFSymbol(&SymRef
->getSymbol());
383 std::string WeakName
= std::string(".weak.")
384 + Symbol
.getName().str()
386 COFFSymbol
*WeakDefault
= createSymbol(WeakName
);
387 WeakDefault
->Data
.SectionNumber
= COFF::IMAGE_SYM_ABSOLUTE
;
388 WeakDefault
->Data
.StorageClass
= COFF::IMAGE_SYM_CLASS_EXTERNAL
;
389 WeakDefault
->Data
.Type
= 0;
390 WeakDefault
->Data
.Value
= 0;
391 coff_symbol
->Other
= WeakDefault
;
394 // Setup the Weak External auxiliary symbol.
395 coff_symbol
->Aux
.resize(1);
396 memset(&coff_symbol
->Aux
[0], 0, sizeof(coff_symbol
->Aux
[0]));
397 coff_symbol
->Aux
[0].AuxType
= ATWeakExternal
;
398 coff_symbol
->Aux
[0].Aux
.WeakExternal
.TagIndex
= 0;
399 coff_symbol
->Aux
[0].Aux
.WeakExternal
.Characteristics
=
400 COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY
;
402 coff_symbol
->MCData
= &SymbolData
;
404 const MCSymbolData
&ResSymData
= Assembler
.getSymbolData(Symbol
);
405 const MCSymbol
*Base
= Layout
.getBaseSymbol(Symbol
);
406 coff_symbol
->Data
.Value
= getSymbolValue(ResSymData
, Layout
);
408 coff_symbol
->Data
.Type
= (ResSymData
.getFlags() & 0x0000FFFF) >> 0;
409 coff_symbol
->Data
.StorageClass
= (ResSymData
.getFlags() & 0x00FF0000) >> 16;
411 // If no storage class was specified in the streamer, define it here.
412 if (coff_symbol
->Data
.StorageClass
== 0) {
414 ResSymData
.isExternal() ||
415 (!ResSymData
.getFragment() && !ResSymData
.getSymbol().isVariable());
417 coff_symbol
->Data
.StorageClass
= IsExternal
418 ? COFF::IMAGE_SYM_CLASS_EXTERNAL
419 : COFF::IMAGE_SYM_CLASS_STATIC
;
423 coff_symbol
->Data
.SectionNumber
= COFF::IMAGE_SYM_ABSOLUTE
;
425 const MCSymbolData
&BaseData
= Assembler
.getSymbolData(*Base
);
426 if (BaseData
.getFragment()) {
428 SectionMap
[&BaseData
.getFragment()->getParent()->getSection()];
430 if (coff_symbol
->Section
&& coff_symbol
->Section
!= Sec
)
431 report_fatal_error("conflicting sections for symbol");
433 coff_symbol
->Section
= Sec
;
437 coff_symbol
->MCData
= &ResSymData
;
441 // Maximum offsets for different string table entry encodings.
442 static const unsigned Max6DecimalOffset
= 999999;
443 static const unsigned Max7DecimalOffset
= 9999999;
444 static const uint64_t MaxBase64Offset
= 0xFFFFFFFFFULL
; // 64^6, including 0
446 // Encode a string table entry offset in base 64, padded to 6 chars, and
447 // prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
448 // Buffer must be at least 8 bytes large. No terminating null appended.
449 static void encodeBase64StringEntry(char* Buffer
, uint64_t Value
) {
450 assert(Value
> Max7DecimalOffset
&& Value
<= MaxBase64Offset
&&
451 "Illegal section name encoding for value");
453 static const char Alphabet
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
454 "abcdefghijklmnopqrstuvwxyz"
460 char* Ptr
= Buffer
+ 7;
461 for (unsigned i
= 0; i
< 6; ++i
) {
462 unsigned Rem
= Value
% 64;
464 *(Ptr
--) = Alphabet
[Rem
];
468 void WinCOFFObjectWriter::SetSectionName(COFFSection
&S
) {
469 if (S
.Name
.size() > COFF::NameSize
) {
470 uint64_t StringTableEntry
= Strings
.getOffset(S
.Name
);
472 if (StringTableEntry
<= Max6DecimalOffset
) {
473 std::sprintf(S
.Header
.Name
, "/%d", unsigned(StringTableEntry
));
474 } else if (StringTableEntry
<= Max7DecimalOffset
) {
475 // With seven digits, we have to skip the terminating null. Because
476 // sprintf always appends it, we use a larger temporary buffer.
477 char buffer
[9] = { };
478 std::sprintf(buffer
, "/%d", unsigned(StringTableEntry
));
479 std::memcpy(S
.Header
.Name
, buffer
, 8);
480 } else if (StringTableEntry
<= MaxBase64Offset
) {
481 // Starting with 10,000,000, offsets are encoded as base64.
482 encodeBase64StringEntry(S
.Header
.Name
, StringTableEntry
);
484 report_fatal_error("COFF string table is greater than 64 GB.");
487 std::memcpy(S
.Header
.Name
, S
.Name
.c_str(), S
.Name
.size());
490 void WinCOFFObjectWriter::SetSymbolName(COFFSymbol
&S
) {
491 if (S
.Name
.size() > COFF::NameSize
)
492 S
.set_name_offset(Strings
.getOffset(S
.Name
));
494 std::memcpy(S
.Data
.Name
, S
.Name
.c_str(), S
.Name
.size());
497 bool WinCOFFObjectWriter::ExportSymbol(const MCSymbol
&Symbol
,
499 // This doesn't seem to be right. Strings referred to from the .data section
500 // need symbols so they can be linked to code in the .text section right?
502 // return Asm.isSymbolLinkerVisible(Symbol);
504 // Non-temporary labels should always be visible to the linker.
505 if (!Symbol
.isTemporary())
508 // Absolute temporary labels are never visible.
509 if (!Symbol
.isInSection())
512 // For now, all non-variable symbols are exported,
513 // the linker will sort the rest out for us.
514 return !Symbol
.isVariable();
517 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection
*S
) {
518 return (S
->Header
.Characteristics
519 & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
) == 0;
522 //------------------------------------------------------------------------------
523 // entity writing methods
525 void WinCOFFObjectWriter::WriteFileHeader(const COFF::header
&Header
) {
527 WriteLE16(COFF::IMAGE_FILE_MACHINE_UNKNOWN
);
529 WriteLE16(COFF::BigObjHeader::MinBigObjectVersion
);
530 WriteLE16(Header
.Machine
);
531 WriteLE32(Header
.TimeDateStamp
);
532 for (uint8_t MagicChar
: COFF::BigObjMagic
)
538 WriteLE32(Header
.NumberOfSections
);
539 WriteLE32(Header
.PointerToSymbolTable
);
540 WriteLE32(Header
.NumberOfSymbols
);
542 WriteLE16(Header
.Machine
);
543 WriteLE16(static_cast<int16_t>(Header
.NumberOfSections
));
544 WriteLE32(Header
.TimeDateStamp
);
545 WriteLE32(Header
.PointerToSymbolTable
);
546 WriteLE32(Header
.NumberOfSymbols
);
547 WriteLE16(Header
.SizeOfOptionalHeader
);
548 WriteLE16(Header
.Characteristics
);
552 void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol
&S
) {
553 WriteBytes(StringRef(S
.Data
.Name
, COFF::NameSize
));
554 WriteLE32(S
.Data
.Value
);
556 WriteLE32(S
.Data
.SectionNumber
);
558 WriteLE16(static_cast<int16_t>(S
.Data
.SectionNumber
));
559 WriteLE16(S
.Data
.Type
);
560 Write8(S
.Data
.StorageClass
);
561 Write8(S
.Data
.NumberOfAuxSymbols
);
562 WriteAuxiliarySymbols(S
.Aux
);
565 void WinCOFFObjectWriter::WriteAuxiliarySymbols(
566 const COFFSymbol::AuxiliarySymbols
&S
) {
567 for(COFFSymbol::AuxiliarySymbols::const_iterator i
= S
.begin(), e
= S
.end();
570 case ATFunctionDefinition
:
571 WriteLE32(i
->Aux
.FunctionDefinition
.TagIndex
);
572 WriteLE32(i
->Aux
.FunctionDefinition
.TotalSize
);
573 WriteLE32(i
->Aux
.FunctionDefinition
.PointerToLinenumber
);
574 WriteLE32(i
->Aux
.FunctionDefinition
.PointerToNextFunction
);
575 WriteZeros(sizeof(i
->Aux
.FunctionDefinition
.unused
));
577 WriteZeros(COFF::Symbol32Size
- COFF::Symbol16Size
);
579 case ATbfAndefSymbol
:
580 WriteZeros(sizeof(i
->Aux
.bfAndefSymbol
.unused1
));
581 WriteLE16(i
->Aux
.bfAndefSymbol
.Linenumber
);
582 WriteZeros(sizeof(i
->Aux
.bfAndefSymbol
.unused2
));
583 WriteLE32(i
->Aux
.bfAndefSymbol
.PointerToNextFunction
);
584 WriteZeros(sizeof(i
->Aux
.bfAndefSymbol
.unused3
));
586 WriteZeros(COFF::Symbol32Size
- COFF::Symbol16Size
);
589 WriteLE32(i
->Aux
.WeakExternal
.TagIndex
);
590 WriteLE32(i
->Aux
.WeakExternal
.Characteristics
);
591 WriteZeros(sizeof(i
->Aux
.WeakExternal
.unused
));
593 WriteZeros(COFF::Symbol32Size
- COFF::Symbol16Size
);
597 StringRef(reinterpret_cast<const char *>(&i
->Aux
),
598 UseBigObj
? COFF::Symbol32Size
: COFF::Symbol16Size
));
600 case ATSectionDefinition
:
601 WriteLE32(i
->Aux
.SectionDefinition
.Length
);
602 WriteLE16(i
->Aux
.SectionDefinition
.NumberOfRelocations
);
603 WriteLE16(i
->Aux
.SectionDefinition
.NumberOfLinenumbers
);
604 WriteLE32(i
->Aux
.SectionDefinition
.CheckSum
);
605 WriteLE16(static_cast<int16_t>(i
->Aux
.SectionDefinition
.Number
));
606 Write8(i
->Aux
.SectionDefinition
.Selection
);
607 WriteZeros(sizeof(i
->Aux
.SectionDefinition
.unused
));
608 WriteLE16(static_cast<int16_t>(i
->Aux
.SectionDefinition
.Number
>> 16));
610 WriteZeros(COFF::Symbol32Size
- COFF::Symbol16Size
);
616 void WinCOFFObjectWriter::WriteSectionHeader(const COFF::section
&S
) {
617 WriteBytes(StringRef(S
.Name
, COFF::NameSize
));
619 WriteLE32(S
.VirtualSize
);
620 WriteLE32(S
.VirtualAddress
);
621 WriteLE32(S
.SizeOfRawData
);
622 WriteLE32(S
.PointerToRawData
);
623 WriteLE32(S
.PointerToRelocations
);
624 WriteLE32(S
.PointerToLineNumbers
);
625 WriteLE16(S
.NumberOfRelocations
);
626 WriteLE16(S
.NumberOfLineNumbers
);
627 WriteLE32(S
.Characteristics
);
630 void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation
&R
) {
631 WriteLE32(R
.VirtualAddress
);
632 WriteLE32(R
.SymbolTableIndex
);
636 ////////////////////////////////////////////////////////////////////////////////
637 // MCObjectWriter interface implementations
639 void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler
&Asm
,
640 const MCAsmLayout
&Layout
) {
641 // "Define" each section & symbol. This creates section & symbol
642 // entries in the staging area.
643 for (const auto &Section
: Asm
)
644 DefineSection(Section
);
646 for (MCSymbolData
&SD
: Asm
.symbols())
647 if (ExportSymbol(SD
.getSymbol(), Asm
))
648 DefineSymbol(SD
, Asm
, Layout
);
651 bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
652 const MCAssembler
&Asm
, const MCSymbolData
&DataA
, const MCFragment
&FB
,
653 bool InSet
, bool IsPCRel
) const {
654 // MS LINK expects to be able to replace all references to a function with a
655 // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize
656 // away any relocations to functions.
657 if ((((DataA
.getFlags() & COFF::SF_TypeMask
) >> COFF::SF_TypeShift
) >>
658 COFF::SCT_COMPLEX_TYPE_SHIFT
) == COFF::IMAGE_SYM_DTYPE_FUNCTION
)
660 return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm
, DataA
, FB
,
664 void WinCOFFObjectWriter::RecordRelocation(const MCAssembler
&Asm
,
665 const MCAsmLayout
&Layout
,
666 const MCFragment
*Fragment
,
667 const MCFixup
&Fixup
,
670 uint64_t &FixedValue
) {
671 assert(Target
.getSymA() && "Relocation must reference a symbol!");
673 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
674 const MCSymbol
&A
= Symbol
.AliasedSymbol();
675 if (!Asm
.hasSymbolData(A
))
676 Asm
.getContext().FatalError(
678 Twine("symbol '") + A
.getName() + "' can not be undefined");
680 const MCSymbolData
&A_SD
= Asm
.getSymbolData(A
);
682 MCSectionData
const *SectionData
= Fragment
->getParent();
684 // Mark this symbol as requiring an entry in the symbol table.
685 assert(SectionMap
.find(&SectionData
->getSection()) != SectionMap
.end() &&
686 "Section must already have been defined in ExecutePostLayoutBinding!");
687 assert(SymbolMap
.find(&A_SD
.getSymbol()) != SymbolMap
.end() &&
688 "Symbol must already have been defined in ExecutePostLayoutBinding!");
690 COFFSection
*coff_section
= SectionMap
[&SectionData
->getSection()];
691 COFFSymbol
*coff_symbol
= SymbolMap
[&A_SD
.getSymbol()];
692 const MCSymbolRefExpr
*SymB
= Target
.getSymB();
693 bool CrossSection
= false;
696 const MCSymbol
*B
= &SymB
->getSymbol();
697 const MCSymbolData
&B_SD
= Asm
.getSymbolData(*B
);
698 if (!B_SD
.getFragment())
699 Asm
.getContext().FatalError(
701 Twine("symbol '") + B
->getName() +
702 "' can not be undefined in a subtraction expression");
704 if (!A_SD
.getFragment())
705 Asm
.getContext().FatalError(
707 Twine("symbol '") + Symbol
.getName() +
708 "' can not be undefined in a subtraction expression");
710 CrossSection
= &Symbol
.getSection() != &B
->getSection();
712 // Offset of the symbol in the section
713 int64_t OffsetOfB
= Layout
.getSymbolOffset(&B_SD
);
715 // In the case where we have SymbA and SymB, we just need to store the delta
716 // between the two symbols. Update FixedValue to account for the delta, and
717 // skip recording the relocation.
719 int64_t OffsetOfA
= Layout
.getSymbolOffset(&A_SD
);
720 FixedValue
= (OffsetOfA
- OffsetOfB
) + Target
.getConstant();
724 // Offset of the relocation in the section
725 int64_t OffsetOfRelocation
=
726 Layout
.getFragmentOffset(Fragment
) + Fixup
.getOffset();
728 FixedValue
= OffsetOfRelocation
- OffsetOfB
;
730 FixedValue
= Target
.getConstant();
733 COFFRelocation Reloc
;
735 Reloc
.Data
.SymbolTableIndex
= 0;
736 Reloc
.Data
.VirtualAddress
= Layout
.getFragmentOffset(Fragment
);
738 // Turn relocations for temporary symbols into section relocations.
739 if (coff_symbol
->MCData
->getSymbol().isTemporary() || CrossSection
) {
740 Reloc
.Symb
= coff_symbol
->Section
->Symbol
;
741 FixedValue
+= Layout
.getFragmentOffset(coff_symbol
->MCData
->getFragment()) +
742 coff_symbol
->MCData
->getOffset();
744 Reloc
.Symb
= coff_symbol
;
746 ++Reloc
.Symb
->Relocations
;
748 Reloc
.Data
.VirtualAddress
+= Fixup
.getOffset();
749 Reloc
.Data
.Type
= TargetObjectWriter
->getRelocType(Target
, Fixup
,
752 // FIXME: Can anyone explain what this does other than adjust for the size
754 if ((Header
.Machine
== COFF::IMAGE_FILE_MACHINE_AMD64
&&
755 Reloc
.Data
.Type
== COFF::IMAGE_REL_AMD64_REL32
) ||
756 (Header
.Machine
== COFF::IMAGE_FILE_MACHINE_I386
&&
757 Reloc
.Data
.Type
== COFF::IMAGE_REL_I386_REL32
))
760 if (Header
.Machine
== COFF::IMAGE_FILE_MACHINE_ARMNT
) {
761 switch (Reloc
.Data
.Type
) {
762 case COFF::IMAGE_REL_ARM_ABSOLUTE
:
763 case COFF::IMAGE_REL_ARM_ADDR32
:
764 case COFF::IMAGE_REL_ARM_ADDR32NB
:
765 case COFF::IMAGE_REL_ARM_TOKEN
:
766 case COFF::IMAGE_REL_ARM_SECTION
:
767 case COFF::IMAGE_REL_ARM_SECREL
:
769 case COFF::IMAGE_REL_ARM_BRANCH11
:
770 case COFF::IMAGE_REL_ARM_BLX11
:
771 // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
772 // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
774 case COFF::IMAGE_REL_ARM_BRANCH24
:
775 case COFF::IMAGE_REL_ARM_BLX24
:
776 case COFF::IMAGE_REL_ARM_MOV32A
:
777 // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
778 // only used for ARM mode code, which is documented as being unsupported
779 // by Windows on ARM. Empirical proof indicates that masm is able to
780 // generate the relocations however the rest of the MSVC toolchain is
781 // unable to handle it.
782 llvm_unreachable("unsupported relocation");
784 case COFF::IMAGE_REL_ARM_MOV32T
:
786 case COFF::IMAGE_REL_ARM_BRANCH20T
:
787 case COFF::IMAGE_REL_ARM_BRANCH24T
:
788 case COFF::IMAGE_REL_ARM_BLX23T
:
789 // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
790 // perform a 4 byte adjustment to the relocation. Relative branches are
791 // offset by 4 on ARM, however, because there is no RELA relocations, all
792 // branches are offset by 4.
793 FixedValue
= FixedValue
+ 4;
798 if (TargetObjectWriter
->recordRelocation(Fixup
))
799 coff_section
->Relocations
.push_back(Reloc
);
802 void WinCOFFObjectWriter::WriteObject(MCAssembler
&Asm
,
803 const MCAsmLayout
&Layout
) {
804 size_t SectionsSize
= Sections
.size();
805 if (SectionsSize
> static_cast<size_t>(INT32_MAX
))
807 "PE COFF object files can't have more than 2147483647 sections");
809 // Assign symbol and section indexes and offsets.
810 int32_t NumberOfSections
= static_cast<int32_t>(SectionsSize
);
812 UseBigObj
= NumberOfSections
> COFF::MaxNumberOfSections16
;
814 DenseMap
<COFFSection
*, int32_t> SectionIndices(
815 NextPowerOf2(NumberOfSections
));
817 // Assign section numbers.
819 for (const auto &Section
: Sections
) {
820 SectionIndices
[Section
.get()] = Number
;
821 Section
->Number
= Number
;
822 Section
->Symbol
->Data
.SectionNumber
= Number
;
823 Section
->Symbol
->Aux
[0].Aux
.SectionDefinition
.Number
= Number
;
827 Header
.NumberOfSections
= NumberOfSections
;
828 Header
.NumberOfSymbols
= 0;
830 for (auto FI
= Asm
.file_names_begin(), FE
= Asm
.file_names_end();
832 // round up to calculate the number of auxiliary symbols required
833 unsigned SymbolSize
= UseBigObj
? COFF::Symbol32Size
: COFF::Symbol16Size
;
834 unsigned Count
= (FI
->size() + SymbolSize
- 1) / SymbolSize
;
836 COFFSymbol
*file
= createSymbol(".file");
837 file
->Data
.SectionNumber
= COFF::IMAGE_SYM_DEBUG
;
838 file
->Data
.StorageClass
= COFF::IMAGE_SYM_CLASS_FILE
;
839 file
->Aux
.resize(Count
);
842 unsigned Length
= FI
->size();
843 for (auto &Aux
: file
->Aux
) {
844 Aux
.AuxType
= ATFile
;
846 if (Length
> SymbolSize
) {
847 memcpy(&Aux
.Aux
, FI
->c_str() + Offset
, SymbolSize
);
848 Length
= Length
- SymbolSize
;
850 memcpy(&Aux
.Aux
, FI
->c_str() + Offset
, Length
);
851 memset((char *)&Aux
.Aux
+ Length
, 0, SymbolSize
- Length
);
855 Offset
+= SymbolSize
;
859 for (auto &Symbol
: Symbols
) {
860 // Update section number & offset for symbols that have them.
862 Symbol
->Data
.SectionNumber
= Symbol
->Section
->Number
;
863 if (Symbol
->should_keep()) {
864 Symbol
->Index
= Header
.NumberOfSymbols
++;
865 // Update auxiliary symbol info.
866 Symbol
->Data
.NumberOfAuxSymbols
= Symbol
->Aux
.size();
867 Header
.NumberOfSymbols
+= Symbol
->Data
.NumberOfAuxSymbols
;
872 // Build string table.
873 for (const auto &S
: Sections
)
874 if (S
->Name
.size() > COFF::NameSize
)
875 Strings
.add(S
->Name
);
876 for (const auto &S
: Symbols
)
877 if (S
->should_keep() && S
->Name
.size() > COFF::NameSize
)
878 Strings
.add(S
->Name
);
879 Strings
.finalize(StringTableBuilder::WinCOFF
);
882 for (const auto &S
: Sections
)
884 for (auto &S
: Symbols
)
885 if (S
->should_keep())
888 // Fixup weak external references.
889 for (auto &Symbol
: Symbols
) {
891 assert(Symbol
->Index
!= -1);
892 assert(Symbol
->Aux
.size() == 1 && "Symbol must contain one aux symbol!");
893 assert(Symbol
->Aux
[0].AuxType
== ATWeakExternal
&&
894 "Symbol's aux symbol must be a Weak External!");
895 Symbol
->Aux
[0].Aux
.WeakExternal
.TagIndex
= Symbol
->Other
->Index
;
899 // Fixup associative COMDAT sections.
900 for (auto &Section
: Sections
) {
901 if (Section
->Symbol
->Aux
[0].Aux
.SectionDefinition
.Selection
!=
902 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE
)
905 const MCSectionCOFF
&MCSec
=
906 static_cast<const MCSectionCOFF
&>(Section
->MCData
->getSection());
908 const MCSymbol
*COMDAT
= MCSec
.getCOMDATSymbol();
910 COFFSymbol
*COMDATSymbol
= GetOrCreateCOFFSymbol(COMDAT
);
911 assert(COMDATSymbol
);
912 COFFSection
*Assoc
= COMDATSymbol
->Section
;
915 Twine("Missing associated COMDAT section for section ") +
916 MCSec
.getSectionName());
918 // Skip this section if the associated section is unused.
919 if (Assoc
->Number
== -1)
922 Section
->Symbol
->Aux
[0].Aux
.SectionDefinition
.Number
= SectionIndices
[Assoc
];
926 // Assign file offsets to COFF object file structures.
931 offset
+= COFF::Header32Size
;
933 offset
+= COFF::Header16Size
;
934 offset
+= COFF::SectionSize
* Header
.NumberOfSections
;
936 for (const auto &Section
: Asm
) {
937 COFFSection
*Sec
= SectionMap
[&Section
.getSection()];
939 if (Sec
->Number
== -1)
942 Sec
->Header
.SizeOfRawData
= Layout
.getSectionAddressSize(&Section
);
944 if (IsPhysicalSection(Sec
)) {
945 Sec
->Header
.PointerToRawData
= offset
;
947 offset
+= Sec
->Header
.SizeOfRawData
;
950 if (Sec
->Relocations
.size() > 0) {
951 bool RelocationsOverflow
= Sec
->Relocations
.size() >= 0xffff;
953 if (RelocationsOverflow
) {
954 // Signal overflow by setting NumberOfRelocations to max value. Actual
955 // size is found in reloc #0. Microsoft tools understand this.
956 Sec
->Header
.NumberOfRelocations
= 0xffff;
958 Sec
->Header
.NumberOfRelocations
= Sec
->Relocations
.size();
960 Sec
->Header
.PointerToRelocations
= offset
;
962 if (RelocationsOverflow
) {
963 // Reloc #0 will contain actual count, so make room for it.
964 offset
+= COFF::RelocationSize
;
967 offset
+= COFF::RelocationSize
* Sec
->Relocations
.size();
969 for (auto &Relocation
: Sec
->Relocations
) {
970 assert(Relocation
.Symb
->Index
!= -1);
971 Relocation
.Data
.SymbolTableIndex
= Relocation
.Symb
->Index
;
975 assert(Sec
->Symbol
->Aux
.size() == 1 &&
976 "Section's symbol must have one aux!");
977 AuxSymbol
&Aux
= Sec
->Symbol
->Aux
[0];
978 assert(Aux
.AuxType
== ATSectionDefinition
&&
979 "Section's symbol's aux symbol must be a Section Definition!");
980 Aux
.Aux
.SectionDefinition
.Length
= Sec
->Header
.SizeOfRawData
;
981 Aux
.Aux
.SectionDefinition
.NumberOfRelocations
=
982 Sec
->Header
.NumberOfRelocations
;
983 Aux
.Aux
.SectionDefinition
.NumberOfLinenumbers
=
984 Sec
->Header
.NumberOfLineNumbers
;
987 Header
.PointerToSymbolTable
= offset
;
989 // We want a deterministic output. It looks like GNU as also writes 0 in here.
990 Header
.TimeDateStamp
= 0;
992 // Write it all to disk...
993 WriteFileHeader(Header
);
996 sections::iterator i
, ie
;
997 MCAssembler::const_iterator j
, je
;
999 for (auto &Section
: Sections
) {
1000 if (Section
->Number
!= -1) {
1001 if (Section
->Relocations
.size() >= 0xffff)
1002 Section
->Header
.Characteristics
|= COFF::IMAGE_SCN_LNK_NRELOC_OVFL
;
1003 WriteSectionHeader(Section
->Header
);
1007 for (i
= Sections
.begin(), ie
= Sections
.end(),
1008 j
= Asm
.begin(), je
= Asm
.end();
1009 (i
!= ie
) && (j
!= je
); ++i
, ++j
) {
1011 if ((*i
)->Number
== -1)
1014 if ((*i
)->Header
.PointerToRawData
!= 0) {
1015 assert(OS
.tell() == (*i
)->Header
.PointerToRawData
&&
1016 "Section::PointerToRawData is insane!");
1018 Asm
.writeSectionData(j
, Layout
);
1021 if ((*i
)->Relocations
.size() > 0) {
1022 assert(OS
.tell() == (*i
)->Header
.PointerToRelocations
&&
1023 "Section::PointerToRelocations is insane!");
1025 if ((*i
)->Relocations
.size() >= 0xffff) {
1026 // In case of overflow, write actual relocation count as first
1027 // relocation. Including the synthetic reloc itself (+ 1).
1029 r
.VirtualAddress
= (*i
)->Relocations
.size() + 1;
1030 r
.SymbolTableIndex
= 0;
1035 for (const auto &Relocation
: (*i
)->Relocations
)
1036 WriteRelocation(Relocation
.Data
);
1038 assert((*i
)->Header
.PointerToRelocations
== 0 &&
1039 "Section::PointerToRelocations is insane!");
1043 assert(OS
.tell() == Header
.PointerToSymbolTable
&&
1044 "Header::PointerToSymbolTable is insane!");
1046 for (auto &Symbol
: Symbols
)
1047 if (Symbol
->Index
!= -1)
1048 WriteSymbol(*Symbol
);
1050 OS
.write(Strings
.data().data(), Strings
.data().size());
1053 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_
) :
1057 // Pin the vtable to this file.
1058 void MCWinCOFFObjectTargetWriter::anchor() {}
1060 //------------------------------------------------------------------------------
1061 // WinCOFFObjectWriter factory function
1064 MCObjectWriter
*createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter
*MOTW
,
1066 return new WinCOFFObjectWriter(MOTW
, OS
);