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 #define DEBUG_TYPE "WinCOFFObjectWriter"
16 #include "llvm/MC/MCObjectWriter.h"
17 #include "llvm/MC/MCSection.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCValue.h"
22 #include "llvm/MC/MCAssembler.h"
23 #include "llvm/MC/MCAsmLayout.h"
24 #include "llvm/MC/MCSectionCOFF.h"
26 #include "llvm/ADT/DenseMap.h"
27 #include "llvm/ADT/StringMap.h"
28 #include "llvm/ADT/StringRef.h"
30 #include "llvm/Support/COFF.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/TimeValue.h"
36 #include "../Target/X86/X86FixupKinds.h"
43 typedef llvm::SmallString
<COFF::NameSize
> name
;
54 AuxiliaryType AuxType
;
65 typedef llvm::SmallVector
<AuxSymbol
, 1> AuxiliarySymbols
;
74 MCSymbolData
const *MCData
;
76 COFFSymbol(llvm::StringRef name
);
78 void set_name_offset(uint32_t Offset
);
80 bool should_keep() const;
83 // This class contains staging data for a COFF relocation entry.
84 struct COFFRelocation
{
85 COFF::relocation Data
;
88 COFFRelocation() : Symb(NULL
) {}
89 static size_t size() { return COFF::RelocationSize
; }
92 typedef std::vector
<COFFRelocation
> relocations
;
100 MCSectionData
const *MCData
;
102 relocations Relocations
;
104 COFFSection(llvm::StringRef name
);
105 static size_t size();
108 // This class holds the COFF string table.
110 typedef llvm::StringMap
<size_t> map
;
113 void update_length();
115 std::vector
<char> Data
;
119 size_t insert(llvm::StringRef String
);
122 class WinCOFFObjectWriter
: public MCObjectWriter
{
125 typedef std::vector
<COFFSymbol
*> symbols
;
126 typedef std::vector
<COFFSection
*> sections
;
128 typedef DenseMap
<MCSymbol
const *, COFFSymbol
*> symbol_map
;
129 typedef DenseMap
<MCSection
const *, COFFSection
*> section_map
;
131 // Root level file contents.
138 // Maps used during object file creation.
139 section_map SectionMap
;
140 symbol_map SymbolMap
;
142 WinCOFFObjectWriter(raw_ostream
&OS
, bool is64Bit
);
143 ~WinCOFFObjectWriter();
145 COFFSymbol
*createSymbol(StringRef Name
);
146 COFFSymbol
*GetOrCreateCOFFSymbol(const MCSymbol
* Symbol
);
147 COFFSection
*createSection(StringRef Name
);
149 template <typename object_t
, typename list_t
>
150 object_t
*createCOFFEntity(llvm::StringRef Name
, list_t
&List
);
152 void DefineSection(MCSectionData
const &SectionData
);
153 void DefineSymbol(MCSymbolData
const &SymbolData
, MCAssembler
&Assembler
);
155 void MakeSymbolReal(COFFSymbol
&S
, size_t Index
);
156 void MakeSectionReal(COFFSection
&S
, size_t Number
);
158 bool ExportSection(COFFSection
const *S
);
159 bool ExportSymbol(MCSymbolData
const &SymbolData
, MCAssembler
&Asm
);
161 bool IsPhysicalSection(COFFSection
*S
);
163 // Entity writing methods.
165 void WriteFileHeader(const COFF::header
&Header
);
166 void WriteSymbol(const COFFSymbol
*S
);
167 void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols
&S
);
168 void WriteSectionHeader(const COFF::section
&S
);
169 void WriteRelocation(const COFF::relocation
&R
);
171 // MCObjectWriter interface implementation.
173 void ExecutePostLayoutBinding(MCAssembler
&Asm
, const MCAsmLayout
&Layout
);
175 void RecordRelocation(const MCAssembler
&Asm
,
176 const MCAsmLayout
&Layout
,
177 const MCFragment
*Fragment
,
178 const MCFixup
&Fixup
,
180 uint64_t &FixedValue
);
182 void WriteObject(MCAssembler
&Asm
, const MCAsmLayout
&Layout
);
186 static inline void write_uint32_le(void *Data
, uint32_t const &Value
) {
187 uint8_t *Ptr
= reinterpret_cast<uint8_t *>(Data
);
188 Ptr
[0] = (Value
& 0x000000FF) >> 0;
189 Ptr
[1] = (Value
& 0x0000FF00) >> 8;
190 Ptr
[2] = (Value
& 0x00FF0000) >> 16;
191 Ptr
[3] = (Value
& 0xFF000000) >> 24;
194 static inline void write_uint16_le(void *Data
, uint16_t const &Value
) {
195 uint8_t *Ptr
= reinterpret_cast<uint8_t *>(Data
);
196 Ptr
[0] = (Value
& 0x00FF) >> 0;
197 Ptr
[1] = (Value
& 0xFF00) >> 8;
200 static inline void write_uint8_le(void *Data
, uint8_t const &Value
) {
201 uint8_t *Ptr
= reinterpret_cast<uint8_t *>(Data
);
202 Ptr
[0] = (Value
& 0xFF) >> 0;
205 //------------------------------------------------------------------------------
206 // Symbol class implementation
208 COFFSymbol::COFFSymbol(llvm::StringRef name
)
209 : Name(name
.begin(), name
.end())
214 memset(&Data
, 0, sizeof(Data
));
217 size_t COFFSymbol::size() const {
218 return COFF::SymbolSize
+ (Data
.NumberOfAuxSymbols
* COFF::SymbolSize
);
221 // In the case that the name does not fit within 8 bytes, the offset
222 // into the string table is stored in the last 4 bytes instead, leaving
223 // the first 4 bytes as 0.
224 void COFFSymbol::set_name_offset(uint32_t Offset
) {
225 write_uint32_le(Data
.Name
+ 0, 0);
226 write_uint32_le(Data
.Name
+ 4, Offset
);
229 /// logic to decide if the symbol should be reported in the symbol table
230 bool COFFSymbol::should_keep() const {
231 // no section means its external, keep it
235 // if it has relocations pointing at it, keep it
236 if (Relocations
> 0) {
237 assert(Section
->Number
!= -1 && "Sections with relocations must be real!");
241 // if the section its in is being droped, drop it
242 if (Section
->Number
== -1)
245 // if it is the section symbol, keep it
246 if (Section
->Symbol
== this)
249 // if its temporary, drop it
250 if (MCData
&& MCData
->getSymbol().isTemporary())
253 // otherwise, keep it
257 //------------------------------------------------------------------------------
258 // Section class implementation
260 COFFSection::COFFSection(llvm::StringRef name
)
264 memset(&Header
, 0, sizeof(Header
));
267 size_t COFFSection::size() {
268 return COFF::SectionSize
;
271 //------------------------------------------------------------------------------
272 // StringTable class implementation
274 /// Write the length of the string table into Data.
275 /// The length of the string table includes uint32 length header.
276 void StringTable::update_length() {
277 write_uint32_le(&Data
.front(), Data
.size());
280 StringTable::StringTable() {
281 // The string table data begins with the length of the entire string table
282 // including the length header. Allocate space for this header.
286 size_t StringTable::size() const {
290 /// Add String to the table iff it is not already there.
291 /// @returns the index into the string table where the string is now located.
292 size_t StringTable::insert(llvm::StringRef String
) {
293 map::iterator i
= Map
.find(String
);
298 size_t Offset
= Data
.size();
300 // Insert string data into string table.
301 Data
.insert(Data
.end(), String
.begin(), String
.end());
302 Data
.push_back('\0');
304 // Put a reference to it in the map.
305 Map
[String
] = Offset
;
307 // Update the internal length field.
313 //------------------------------------------------------------------------------
314 // WinCOFFObjectWriter class implementation
316 WinCOFFObjectWriter::WinCOFFObjectWriter(raw_ostream
&OS
, bool is64Bit
)
317 : MCObjectWriter(OS
, true)
319 memset(&Header
, 0, sizeof(Header
));
321 Is64Bit
? Header
.Machine
= COFF::IMAGE_FILE_MACHINE_AMD64
322 : Header
.Machine
= COFF::IMAGE_FILE_MACHINE_I386
;
325 WinCOFFObjectWriter::~WinCOFFObjectWriter() {
326 for (symbols::iterator I
= Symbols
.begin(), E
= Symbols
.end(); I
!= E
; ++I
)
328 for (sections::iterator I
= Sections
.begin(), E
= Sections
.end(); I
!= E
; ++I
)
332 COFFSymbol
*WinCOFFObjectWriter::createSymbol(StringRef Name
) {
333 return createCOFFEntity
<COFFSymbol
>(Name
, Symbols
);
336 COFFSymbol
*WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol
* Symbol
){
337 symbol_map::iterator i
= SymbolMap
.find(Symbol
);
338 if (i
!= SymbolMap
.end())
340 COFFSymbol
*RetSymbol
341 = createCOFFEntity
<COFFSymbol
>(Symbol
->getName(), Symbols
);
342 SymbolMap
[Symbol
] = RetSymbol
;
346 COFFSection
*WinCOFFObjectWriter::createSection(llvm::StringRef Name
) {
347 return createCOFFEntity
<COFFSection
>(Name
, Sections
);
350 /// A template used to lookup or create a symbol/section, and initialize it if
352 template <typename object_t
, typename list_t
>
353 object_t
*WinCOFFObjectWriter::createCOFFEntity(llvm::StringRef Name
,
355 object_t
*Object
= new object_t(Name
);
357 List
.push_back(Object
);
362 /// This function takes a section data object from the assembler
363 /// and creates the associated COFF section staging object.
364 void WinCOFFObjectWriter::DefineSection(MCSectionData
const &SectionData
) {
365 assert(SectionData
.getSection().getVariant() == MCSection::SV_COFF
366 && "Got non COFF section in the COFF backend!");
367 // FIXME: Not sure how to verify this (at least in a debug build).
368 MCSectionCOFF
const &Sec
=
369 static_cast<MCSectionCOFF
const &>(SectionData
.getSection());
371 COFFSection
*coff_section
= createSection(Sec
.getSectionName());
372 COFFSymbol
*coff_symbol
= createSymbol(Sec
.getSectionName());
374 coff_section
->Symbol
= coff_symbol
;
375 coff_symbol
->Section
= coff_section
;
376 coff_symbol
->Data
.StorageClass
= COFF::IMAGE_SYM_CLASS_STATIC
;
378 // In this case the auxiliary symbol is a Section Definition.
379 coff_symbol
->Aux
.resize(1);
380 memset(&coff_symbol
->Aux
[0], 0, sizeof(coff_symbol
->Aux
[0]));
381 coff_symbol
->Aux
[0].AuxType
= ATSectionDefinition
;
382 coff_symbol
->Aux
[0].Aux
.SectionDefinition
.Selection
= Sec
.getSelection();
384 coff_section
->Header
.Characteristics
= Sec
.getCharacteristics();
386 uint32_t &Characteristics
= coff_section
->Header
.Characteristics
;
387 switch (SectionData
.getAlignment()) {
388 case 1: Characteristics
|= COFF::IMAGE_SCN_ALIGN_1BYTES
; break;
389 case 2: Characteristics
|= COFF::IMAGE_SCN_ALIGN_2BYTES
; break;
390 case 4: Characteristics
|= COFF::IMAGE_SCN_ALIGN_4BYTES
; break;
391 case 8: Characteristics
|= COFF::IMAGE_SCN_ALIGN_8BYTES
; break;
392 case 16: Characteristics
|= COFF::IMAGE_SCN_ALIGN_16BYTES
; break;
393 case 32: Characteristics
|= COFF::IMAGE_SCN_ALIGN_32BYTES
; break;
394 case 64: Characteristics
|= COFF::IMAGE_SCN_ALIGN_64BYTES
; break;
395 case 128: Characteristics
|= COFF::IMAGE_SCN_ALIGN_128BYTES
; break;
396 case 256: Characteristics
|= COFF::IMAGE_SCN_ALIGN_256BYTES
; break;
397 case 512: Characteristics
|= COFF::IMAGE_SCN_ALIGN_512BYTES
; break;
398 case 1024: Characteristics
|= COFF::IMAGE_SCN_ALIGN_1024BYTES
; break;
399 case 2048: Characteristics
|= COFF::IMAGE_SCN_ALIGN_2048BYTES
; break;
400 case 4096: Characteristics
|= COFF::IMAGE_SCN_ALIGN_4096BYTES
; break;
401 case 8192: Characteristics
|= COFF::IMAGE_SCN_ALIGN_8192BYTES
; break;
403 llvm_unreachable("unsupported section alignment");
406 // Bind internal COFF section to MC section.
407 coff_section
->MCData
= &SectionData
;
408 SectionMap
[&SectionData
.getSection()] = coff_section
;
411 /// This function takes a section data object from the assembler
412 /// and creates the associated COFF symbol staging object.
413 void WinCOFFObjectWriter::DefineSymbol(MCSymbolData
const &SymbolData
,
414 MCAssembler
&Assembler
) {
415 COFFSymbol
*coff_symbol
= GetOrCreateCOFFSymbol(&SymbolData
.getSymbol());
417 coff_symbol
->Data
.Type
= (SymbolData
.getFlags() & 0x0000FFFF) >> 0;
418 coff_symbol
->Data
.StorageClass
= (SymbolData
.getFlags() & 0x00FF0000) >> 16;
420 if (SymbolData
.getFlags() & COFF::SF_WeakExternal
) {
421 coff_symbol
->Data
.StorageClass
= COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
;
423 if (SymbolData
.getSymbol().isVariable()) {
424 coff_symbol
->Data
.StorageClass
= COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
;
425 const MCExpr
*Value
= SymbolData
.getSymbol().getVariableValue();
427 // FIXME: This assert message isn't very good.
428 assert(Value
->getKind() == MCExpr::SymbolRef
&&
429 "Value must be a SymbolRef!");
431 const MCSymbolRefExpr
*SymbolRef
=
432 static_cast<const MCSymbolRefExpr
*>(Value
);
433 coff_symbol
->Other
= GetOrCreateCOFFSymbol(&SymbolRef
->getSymbol());
435 std::string WeakName
= std::string(".weak.")
436 + SymbolData
.getSymbol().getName().str()
438 COFFSymbol
*WeakDefault
= createSymbol(WeakName
);
439 WeakDefault
->Data
.SectionNumber
= COFF::IMAGE_SYM_ABSOLUTE
;
440 WeakDefault
->Data
.StorageClass
= COFF::IMAGE_SYM_CLASS_EXTERNAL
;
441 WeakDefault
->Data
.Type
= 0;
442 WeakDefault
->Data
.Value
= 0;
443 coff_symbol
->Other
= WeakDefault
;
446 // Setup the Weak External auxiliary symbol.
447 coff_symbol
->Aux
.resize(1);
448 memset(&coff_symbol
->Aux
[0], 0, sizeof(coff_symbol
->Aux
[0]));
449 coff_symbol
->Aux
[0].AuxType
= ATWeakExternal
;
450 coff_symbol
->Aux
[0].Aux
.WeakExternal
.TagIndex
= 0;
451 coff_symbol
->Aux
[0].Aux
.WeakExternal
.Characteristics
=
452 COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY
;
455 // If no storage class was specified in the streamer, define it here.
456 if (coff_symbol
->Data
.StorageClass
== 0) {
457 bool external
= SymbolData
.isExternal() || (SymbolData
.Fragment
== NULL
);
459 coff_symbol
->Data
.StorageClass
=
460 external
? COFF::IMAGE_SYM_CLASS_EXTERNAL
: COFF::IMAGE_SYM_CLASS_STATIC
;
463 if (SymbolData
.Fragment
!= NULL
)
464 coff_symbol
->Section
=
465 SectionMap
[&SymbolData
.Fragment
->getParent()->getSection()];
467 // Bind internal COFF symbol to MC symbol.
468 coff_symbol
->MCData
= &SymbolData
;
469 SymbolMap
[&SymbolData
.getSymbol()] = coff_symbol
;
472 /// making a section real involves assigned it a number and putting
473 /// name into the string table if needed
474 void WinCOFFObjectWriter::MakeSectionReal(COFFSection
&S
, size_t Number
) {
475 if (S
.Name
.size() > COFF::NameSize
) {
476 size_t StringTableEntry
= Strings
.insert(S
.Name
.c_str());
478 // FIXME: Why is this number 999999? This number is never mentioned in the
479 // spec. I'm assuming this is due to the printed value needing to fit into
480 // the S.Header.Name field. In which case why not 9999999 (7 9's instead of
481 // 6)? The spec does not state if this entry should be null terminated in
482 // this case, and thus this seems to be the best way to do it. I think I
483 // just solved my own FIXME...
484 if (StringTableEntry
> 999999)
485 report_fatal_error("COFF string table is greater than 999999 bytes.");
487 std::sprintf(S
.Header
.Name
, "/%d", unsigned(StringTableEntry
));
489 std::memcpy(S
.Header
.Name
, S
.Name
.c_str(), S
.Name
.size());
492 S
.Symbol
->Data
.SectionNumber
= S
.Number
;
493 S
.Symbol
->Aux
[0].Aux
.SectionDefinition
.Number
= S
.Number
;
496 void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol
&S
, size_t Index
) {
497 if (S
.Name
.size() > COFF::NameSize
) {
498 size_t StringTableEntry
= Strings
.insert(S
.Name
.c_str());
500 S
.set_name_offset(StringTableEntry
);
502 std::memcpy(S
.Data
.Name
, S
.Name
.c_str(), S
.Name
.size());
506 bool WinCOFFObjectWriter::ExportSection(COFFSection
const *S
) {
507 return !S
->MCData
->getFragmentList().empty();
510 bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData
const &SymbolData
,
512 // This doesn't seem to be right. Strings referred to from the .data section
513 // need symbols so they can be linked to code in the .text section right?
515 // return Asm.isSymbolLinkerVisible (&SymbolData);
517 // For now, all non-variable symbols are exported,
518 // the linker will sort the rest out for us.
519 return SymbolData
.isExternal() || !SymbolData
.getSymbol().isVariable();
522 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection
*S
) {
523 return (S
->Header
.Characteristics
524 & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
) == 0;
527 //------------------------------------------------------------------------------
528 // entity writing methods
530 void WinCOFFObjectWriter::WriteFileHeader(const COFF::header
&Header
) {
531 WriteLE16(Header
.Machine
);
532 WriteLE16(Header
.NumberOfSections
);
533 WriteLE32(Header
.TimeDateStamp
);
534 WriteLE32(Header
.PointerToSymbolTable
);
535 WriteLE32(Header
.NumberOfSymbols
);
536 WriteLE16(Header
.SizeOfOptionalHeader
);
537 WriteLE16(Header
.Characteristics
);
540 void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol
*S
) {
541 WriteBytes(StringRef(S
->Data
.Name
, COFF::NameSize
));
542 WriteLE32(S
->Data
.Value
);
543 WriteLE16(S
->Data
.SectionNumber
);
544 WriteLE16(S
->Data
.Type
);
545 Write8(S
->Data
.StorageClass
);
546 Write8(S
->Data
.NumberOfAuxSymbols
);
547 WriteAuxiliarySymbols(S
->Aux
);
550 void WinCOFFObjectWriter::WriteAuxiliarySymbols(
551 const COFFSymbol::AuxiliarySymbols
&S
) {
552 for(COFFSymbol::AuxiliarySymbols::const_iterator i
= S
.begin(), e
= S
.end();
555 case ATFunctionDefinition
:
556 WriteLE32(i
->Aux
.FunctionDefinition
.TagIndex
);
557 WriteLE32(i
->Aux
.FunctionDefinition
.TotalSize
);
558 WriteLE32(i
->Aux
.FunctionDefinition
.PointerToLinenumber
);
559 WriteLE32(i
->Aux
.FunctionDefinition
.PointerToNextFunction
);
560 WriteZeros(sizeof(i
->Aux
.FunctionDefinition
.unused
));
562 case ATbfAndefSymbol
:
563 WriteZeros(sizeof(i
->Aux
.bfAndefSymbol
.unused1
));
564 WriteLE16(i
->Aux
.bfAndefSymbol
.Linenumber
);
565 WriteZeros(sizeof(i
->Aux
.bfAndefSymbol
.unused2
));
566 WriteLE32(i
->Aux
.bfAndefSymbol
.PointerToNextFunction
);
567 WriteZeros(sizeof(i
->Aux
.bfAndefSymbol
.unused3
));
570 WriteLE32(i
->Aux
.WeakExternal
.TagIndex
);
571 WriteLE32(i
->Aux
.WeakExternal
.Characteristics
);
572 WriteZeros(sizeof(i
->Aux
.WeakExternal
.unused
));
575 WriteBytes(StringRef(reinterpret_cast<const char *>(i
->Aux
.File
.FileName
),
576 sizeof(i
->Aux
.File
.FileName
)));
578 case ATSectionDefinition
:
579 WriteLE32(i
->Aux
.SectionDefinition
.Length
);
580 WriteLE16(i
->Aux
.SectionDefinition
.NumberOfRelocations
);
581 WriteLE16(i
->Aux
.SectionDefinition
.NumberOfLinenumbers
);
582 WriteLE32(i
->Aux
.SectionDefinition
.CheckSum
);
583 WriteLE16(i
->Aux
.SectionDefinition
.Number
);
584 Write8(i
->Aux
.SectionDefinition
.Selection
);
585 WriteZeros(sizeof(i
->Aux
.SectionDefinition
.unused
));
591 void WinCOFFObjectWriter::WriteSectionHeader(const COFF::section
&S
) {
592 WriteBytes(StringRef(S
.Name
, COFF::NameSize
));
594 WriteLE32(S
.VirtualSize
);
595 WriteLE32(S
.VirtualAddress
);
596 WriteLE32(S
.SizeOfRawData
);
597 WriteLE32(S
.PointerToRawData
);
598 WriteLE32(S
.PointerToRelocations
);
599 WriteLE32(S
.PointerToLineNumbers
);
600 WriteLE16(S
.NumberOfRelocations
);
601 WriteLE16(S
.NumberOfLineNumbers
);
602 WriteLE32(S
.Characteristics
);
605 void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation
&R
) {
606 WriteLE32(R
.VirtualAddress
);
607 WriteLE32(R
.SymbolTableIndex
);
611 ////////////////////////////////////////////////////////////////////////////////
612 // MCObjectWriter interface implementations
614 void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler
&Asm
,
615 const MCAsmLayout
&Layout
) {
616 // "Define" each section & symbol. This creates section & symbol
617 // entries in the staging area.
619 for (MCAssembler::const_iterator i
= Asm
.begin(), e
= Asm
.end(); i
!= e
; i
++)
622 for (MCAssembler::const_symbol_iterator i
= Asm
.symbol_begin(),
623 e
= Asm
.symbol_end(); i
!= e
; i
++) {
624 if (ExportSymbol(*i
, Asm
))
625 DefineSymbol(*i
, Asm
);
629 void WinCOFFObjectWriter::RecordRelocation(const MCAssembler
&Asm
,
630 const MCAsmLayout
&Layout
,
631 const MCFragment
*Fragment
,
632 const MCFixup
&Fixup
,
634 uint64_t &FixedValue
) {
635 assert(Target
.getSymA() != NULL
&& "Relocation must reference a symbol!");
637 const MCSymbol
*A
= &Target
.getSymA()->getSymbol();
638 MCSymbolData
&A_SD
= Asm
.getSymbolData(*A
);
640 MCSectionData
const *SectionData
= Fragment
->getParent();
642 // Mark this symbol as requiring an entry in the symbol table.
643 assert(SectionMap
.find(&SectionData
->getSection()) != SectionMap
.end() &&
644 "Section must already have been defined in ExecutePostLayoutBinding!");
645 assert(SymbolMap
.find(&A_SD
.getSymbol()) != SymbolMap
.end() &&
646 "Symbol must already have been defined in ExecutePostLayoutBinding!");
648 COFFSection
*coff_section
= SectionMap
[&SectionData
->getSection()];
649 COFFSymbol
*coff_symbol
= SymbolMap
[&A_SD
.getSymbol()];
650 const MCSymbolRefExpr
*SymA
= Target
.getSymA();
651 const MCSymbolRefExpr
*SymB
= Target
.getSymB();
652 const bool CrossSection
= SymB
&&
653 &SymA
->getSymbol().getSection() != &SymB
->getSymbol().getSection();
655 if (Target
.getSymB()) {
656 const MCSymbol
*B
= &Target
.getSymB()->getSymbol();
657 MCSymbolData
&B_SD
= Asm
.getSymbolData(*B
);
659 // Offset of the symbol in the section
660 int64_t a
= Layout
.getSymbolOffset(&B_SD
);
662 // Ofeset of the relocation in the section
663 int64_t b
= Layout
.getFragmentOffset(Fragment
) + Fixup
.getOffset();
666 // In the case where we have SymbA and SymB, we just need to store the delta
667 // between the two symbols. Update FixedValue to account for the delta, and
668 // skip recording the relocation.
672 FixedValue
= Target
.getConstant();
675 COFFRelocation Reloc
;
677 Reloc
.Data
.SymbolTableIndex
= 0;
678 Reloc
.Data
.VirtualAddress
= Layout
.getFragmentOffset(Fragment
);
680 // Turn relocations for temporary symbols into section relocations.
681 if (coff_symbol
->MCData
->getSymbol().isTemporary() || CrossSection
) {
682 Reloc
.Symb
= coff_symbol
->Section
->Symbol
;
683 FixedValue
+= Layout
.getFragmentOffset(coff_symbol
->MCData
->Fragment
)
684 + coff_symbol
->MCData
->getOffset();
686 Reloc
.Symb
= coff_symbol
;
688 ++Reloc
.Symb
->Relocations
;
690 Reloc
.Data
.VirtualAddress
+= Fixup
.getOffset();
692 unsigned FixupKind
= Fixup
.getKind();
695 FixupKind
= FK_PCRel_4
;
699 case X86::reloc_riprel_4byte
:
700 case X86::reloc_riprel_4byte_movq_load
:
701 Reloc
.Data
.Type
= Is64Bit
? COFF::IMAGE_REL_AMD64_REL32
702 : COFF::IMAGE_REL_I386_REL32
;
703 // FIXME: Can anyone explain what this does other than adjust for the size
708 case X86::reloc_signed_4byte
:
709 Reloc
.Data
.Type
= Is64Bit
? COFF::IMAGE_REL_AMD64_ADDR32
710 : COFF::IMAGE_REL_I386_DIR32
;
714 Reloc
.Data
.Type
= COFF::IMAGE_REL_AMD64_ADDR64
;
716 llvm_unreachable("unsupported relocation type");
719 llvm_unreachable("unsupported relocation type");
722 coff_section
->Relocations
.push_back(Reloc
);
725 void WinCOFFObjectWriter::WriteObject(MCAssembler
&Asm
,
726 const MCAsmLayout
&Layout
) {
727 // Assign symbol and section indexes and offsets.
728 Header
.NumberOfSections
= 0;
730 for (sections::iterator i
= Sections
.begin(),
731 e
= Sections
.end(); i
!= e
; i
++) {
732 if (Layout
.getSectionAddressSize((*i
)->MCData
) > 0) {
733 MakeSectionReal(**i
, ++Header
.NumberOfSections
);
739 Header
.NumberOfSymbols
= 0;
741 for (symbols::iterator i
= Symbols
.begin(), e
= Symbols
.end(); i
!= e
; i
++) {
742 COFFSymbol
*coff_symbol
= *i
;
743 MCSymbolData
const *SymbolData
= coff_symbol
->MCData
;
745 // Update section number & offset for symbols that have them.
746 if ((SymbolData
!= NULL
) && (SymbolData
->Fragment
!= NULL
)) {
747 assert(coff_symbol
->Section
!= NULL
);
749 coff_symbol
->Data
.SectionNumber
= coff_symbol
->Section
->Number
;
750 coff_symbol
->Data
.Value
= Layout
.getFragmentOffset(SymbolData
->Fragment
)
751 + SymbolData
->Offset
;
754 if (coff_symbol
->should_keep()) {
755 MakeSymbolReal(*coff_symbol
, Header
.NumberOfSymbols
++);
757 // Update auxiliary symbol info.
758 coff_symbol
->Data
.NumberOfAuxSymbols
= coff_symbol
->Aux
.size();
759 Header
.NumberOfSymbols
+= coff_symbol
->Data
.NumberOfAuxSymbols
;
761 coff_symbol
->Index
= -1;
764 // Fixup weak external references.
765 for (symbols::iterator i
= Symbols
.begin(), e
= Symbols
.end(); i
!= e
; i
++) {
766 COFFSymbol
*coff_symbol
= *i
;
767 if (coff_symbol
->Other
!= NULL
) {
768 assert(coff_symbol
->Index
!= -1);
769 assert(coff_symbol
->Aux
.size() == 1 &&
770 "Symbol must contain one aux symbol!");
771 assert(coff_symbol
->Aux
[0].AuxType
== ATWeakExternal
&&
772 "Symbol's aux symbol must be a Weak External!");
773 coff_symbol
->Aux
[0].Aux
.WeakExternal
.TagIndex
= coff_symbol
->Other
->Index
;
777 // Assign file offsets to COFF object file structures.
781 offset
+= COFF::HeaderSize
;
782 offset
+= COFF::SectionSize
* Header
.NumberOfSections
;
784 for (MCAssembler::const_iterator i
= Asm
.begin(),
787 COFFSection
*Sec
= SectionMap
[&i
->getSection()];
789 if (Sec
->Number
== -1)
792 Sec
->Header
.SizeOfRawData
= Layout
.getSectionAddressSize(i
);
794 if (IsPhysicalSection(Sec
)) {
795 Sec
->Header
.PointerToRawData
= offset
;
797 offset
+= Sec
->Header
.SizeOfRawData
;
800 if (Sec
->Relocations
.size() > 0) {
801 Sec
->Header
.NumberOfRelocations
= Sec
->Relocations
.size();
802 Sec
->Header
.PointerToRelocations
= offset
;
804 offset
+= COFF::RelocationSize
* Sec
->Relocations
.size();
806 for (relocations::iterator cr
= Sec
->Relocations
.begin(),
807 er
= Sec
->Relocations
.end();
809 assert((*cr
).Symb
->Index
!= -1);
810 (*cr
).Data
.SymbolTableIndex
= (*cr
).Symb
->Index
;
814 assert(Sec
->Symbol
->Aux
.size() == 1
815 && "Section's symbol must have one aux!");
816 AuxSymbol
&Aux
= Sec
->Symbol
->Aux
[0];
817 assert(Aux
.AuxType
== ATSectionDefinition
&&
818 "Section's symbol's aux symbol must be a Section Definition!");
819 Aux
.Aux
.SectionDefinition
.Length
= Sec
->Header
.SizeOfRawData
;
820 Aux
.Aux
.SectionDefinition
.NumberOfRelocations
=
821 Sec
->Header
.NumberOfRelocations
;
822 Aux
.Aux
.SectionDefinition
.NumberOfLinenumbers
=
823 Sec
->Header
.NumberOfLineNumbers
;
826 Header
.PointerToSymbolTable
= offset
;
828 Header
.TimeDateStamp
= sys::TimeValue::now().toEpochTime();
830 // Write it all to disk...
831 WriteFileHeader(Header
);
834 sections::iterator i
, ie
;
835 MCAssembler::const_iterator j
, je
;
837 for (i
= Sections
.begin(), ie
= Sections
.end(); i
!= ie
; i
++)
838 if ((*i
)->Number
!= -1)
839 WriteSectionHeader((*i
)->Header
);
841 for (i
= Sections
.begin(), ie
= Sections
.end(),
842 j
= Asm
.begin(), je
= Asm
.end();
843 (i
!= ie
) && (j
!= je
); ++i
, ++j
) {
845 if ((*i
)->Number
== -1)
848 if ((*i
)->Header
.PointerToRawData
!= 0) {
849 assert(OS
.tell() == (*i
)->Header
.PointerToRawData
&&
850 "Section::PointerToRawData is insane!");
852 Asm
.WriteSectionData(j
, Layout
);
855 if ((*i
)->Relocations
.size() > 0) {
856 assert(OS
.tell() == (*i
)->Header
.PointerToRelocations
&&
857 "Section::PointerToRelocations is insane!");
859 for (relocations::const_iterator k
= (*i
)->Relocations
.begin(),
860 ke
= (*i
)->Relocations
.end();
862 WriteRelocation(k
->Data
);
865 assert((*i
)->Header
.PointerToRelocations
== 0 &&
866 "Section::PointerToRelocations is insane!");
870 assert(OS
.tell() == Header
.PointerToSymbolTable
&&
871 "Header::PointerToSymbolTable is insane!");
873 for (symbols::iterator i
= Symbols
.begin(), e
= Symbols
.end(); i
!= e
; i
++)
874 if ((*i
)->Index
!= -1)
877 OS
.write((char const *)&Strings
.Data
.front(), Strings
.Data
.size());
880 //------------------------------------------------------------------------------
881 // WinCOFFObjectWriter factory function
884 MCObjectWriter
*createWinCOFFObjectWriter(raw_ostream
&OS
, bool is64Bit
) {
885 return new WinCOFFObjectWriter(OS
, is64Bit
);