14 #define DEBUG_TYPE "WinCOFFObjectWriter"
75 void set_name_offset(uint32_t Offset);
77 bool should_keep()
const;
81 struct COFFRelocation {
85 COFFRelocation() : Symb(NULL) {}
89 typedef std::vector<COFFRelocation> relocations;
99 relocations Relocations;
102 static size_t size();
110 void update_length();
112 std::vector<char> Data;
122 typedef std::vector<COFFSymbol*> symbols;
123 typedef std::vector<COFFSection*> sections;
137 section_map SectionMap;
138 symbol_map SymbolMap;
141 virtual ~WinCOFFObjectWriter();
147 template <
typename object_t,
typename list_t>
154 void MakeSymbolReal(COFFSymbol &S,
size_t Index);
155 void MakeSectionReal(COFFSection &S,
size_t Number);
159 bool IsPhysicalSection(COFFSection *S);
164 void WriteSymbol(
const COFFSymbol *S);
178 uint64_t &FixedValue);
185 uint8_t *Ptr =
reinterpret_cast<uint8_t *
>(Data);
186 Ptr[0] = (Value & 0x000000FF) >> 0;
187 Ptr[1] = (Value & 0x0000FF00) >> 8;
188 Ptr[2] = (Value & 0x00FF0000) >> 16;
189 Ptr[3] = (Value & 0xFF000000) >> 24;
201 memset(&Data, 0,
sizeof(Data));
204 size_t COFFSymbol::size()
const {
211 void COFFSymbol::set_name_offset(uint32_t Offset) {
217 bool COFFSymbol::should_keep()
const {
223 if (Relocations > 0) {
224 assert(
Section->Number != -1 &&
"Sections with relocations must be real!");
251 memset(&Header, 0,
sizeof(Header));
254 size_t COFFSection::size() {
263 void StringTable::update_length() {
267 StringTable::StringTable() {
274 size_t StringTable::size()
const {
281 map::iterator i = Map.find(String);
286 size_t Offset = Data.size();
289 Data.insert(Data.end(), String.
begin(), String.
end());
290 Data.push_back(
'\0');
307 , TargetObjectWriter(MOTW) {
308 memset(&Header, 0,
sizeof(Header));
310 Header.Machine = TargetObjectWriter->getMachine();
313 WinCOFFObjectWriter::~WinCOFFObjectWriter() {
314 for (symbols::iterator
I = Symbols.begin(), E = Symbols.end();
I != E; ++
I)
316 for (sections::iterator
I = Sections.begin(), E = Sections.end();
I != E; ++
I)
320 COFFSymbol *WinCOFFObjectWriter::createSymbol(
StringRef Name) {
321 return createCOFFEntity<COFFSymbol>(
Name, Symbols);
324 COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(
const MCSymbol *
Symbol){
325 symbol_map::iterator i = SymbolMap.find(Symbol);
326 if (i != SymbolMap.end())
328 COFFSymbol *RetSymbol
329 = createCOFFEntity<COFFSymbol>(Symbol->
getName(), Symbols);
330 SymbolMap[
Symbol] = RetSymbol;
334 COFFSection *WinCOFFObjectWriter::createSection(
StringRef Name) {
335 return createCOFFEntity<COFFSection>(
Name, Sections);
340 template <
typename object_t,
typename list_t>
341 object_t *WinCOFFObjectWriter::createCOFFEntity(
StringRef Name,
343 object_t *Object =
new object_t(Name);
345 List.push_back(Object);
352 void WinCOFFObjectWriter::DefineSection(
MCSectionData const &SectionData) {
354 &&
"Got non COFF section in the COFF backend!");
359 COFFSection *
coff_section = createSection(Sec.getSectionName());
360 COFFSymbol *
coff_symbol = createSymbol(Sec.getSectionName());
362 coff_section->Symbol = coff_symbol;
363 coff_symbol->Section = coff_section;
367 coff_symbol->Aux.resize(1);
368 memset(&coff_symbol->Aux[0], 0,
sizeof(coff_symbol->Aux[0]));
369 coff_symbol->Aux[0].AuxType = ATSectionDefinition;
370 coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection();
372 coff_section->Header.Characteristics = Sec.getCharacteristics();
376 case 1: Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES;
break;
377 case 2: Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES;
break;
378 case 4: Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES;
break;
379 case 8: Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES;
break;
380 case 16: Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES;
break;
381 case 32: Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES;
break;
382 case 64: Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES;
break;
383 case 128: Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES;
break;
384 case 256: Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES;
break;
385 case 512: Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES;
break;
386 case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES;
break;
387 case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES;
break;
388 case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES;
break;
389 case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES;
break;
395 coff_section->MCData = &SectionData;
396 SectionMap[&SectionData.
getSection()] = coff_section;
401 void WinCOFFObjectWriter::DefineSymbol(
MCSymbolData const &SymbolData,
405 COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
406 SymbolMap[&
Symbol] = coff_symbol;
418 coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->
getSymbol());
420 std::string WeakName = std::string(
".weak.")
423 COFFSymbol *WeakDefault = createSymbol(WeakName);
426 WeakDefault->Data.Type = 0;
427 WeakDefault->Data.Value = 0;
428 coff_symbol->Other = WeakDefault;
432 coff_symbol->Aux.resize(1);
433 memset(&coff_symbol->Aux[0], 0,
sizeof(coff_symbol->Aux[0]));
434 coff_symbol->Aux[0].AuxType = ATWeakExternal;
435 coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0;
436 coff_symbol->Aux[0].Aux.WeakExternal.Characteristics =
439 coff_symbol->MCData = &SymbolData;
447 coff_symbol->Data.Value = Addr;
450 coff_symbol->Data.Type = (ResSymData.
getFlags() & 0x0000FFFF) >> 0;
451 coff_symbol->Data.StorageClass = (ResSymData.
getFlags() & 0x00FF0000) >> 16;
454 if (coff_symbol->Data.StorageClass == 0) {
457 coff_symbol->Data.StorageClass =
464 coff_symbol->Section =
467 coff_symbol->MCData = &ResSymData;
473 void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S,
size_t Number) {
475 const unsigned Max6DecimalSize = 999999;
476 const unsigned Max7DecimalSize = 9999999;
477 uint64_t StringTableEntry = Strings.insert(S.Name.c_str());
479 if (StringTableEntry <= Max6DecimalSize) {
480 std::sprintf(S.Header.Name,
"/%d",
unsigned(StringTableEntry));
481 }
else if (StringTableEntry <= Max7DecimalSize) {
484 char buffer[9] = { };
485 std::sprintf(buffer,
"/%d",
unsigned(StringTableEntry));
491 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
494 S.Symbol->Data.SectionNumber = S.Number;
495 S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number;
498 void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S,
size_t Index) {
500 size_t StringTableEntry = Strings.insert(S.Name.c_str());
502 S.set_name_offset(StringTableEntry);
504 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
508 bool WinCOFFObjectWriter::ExportSymbol(
MCSymbolData const &SymbolData,
520 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
521 return (S->Header.Characteristics
522 & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0;
528 void WinCOFFObjectWriter::WriteFileHeader(
const COFF::header &Header) {
538 void WinCOFFObjectWriter::WriteSymbol(
const COFFSymbol *S) {
540 WriteLE32(S->Data.Value);
541 WriteLE16(S->Data.SectionNumber);
542 WriteLE16(S->Data.Type);
543 Write8(S->Data.StorageClass);
544 Write8(S->Data.NumberOfAuxSymbols);
545 WriteAuxiliarySymbols(S->Aux);
548 void WinCOFFObjectWriter::WriteAuxiliarySymbols(
553 case ATFunctionDefinition:
554 WriteLE32(i->Aux.FunctionDefinition.TagIndex);
555 WriteLE32(i->Aux.FunctionDefinition.TotalSize);
556 WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber);
557 WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction);
558 WriteZeros(
sizeof(i->Aux.FunctionDefinition.unused));
560 case ATbfAndefSymbol:
561 WriteZeros(
sizeof(i->Aux.bfAndefSymbol.unused1));
562 WriteLE16(i->Aux.bfAndefSymbol.Linenumber);
563 WriteZeros(
sizeof(i->Aux.bfAndefSymbol.unused2));
564 WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction);
565 WriteZeros(
sizeof(i->Aux.bfAndefSymbol.unused3));
568 WriteLE32(i->Aux.WeakExternal.TagIndex);
569 WriteLE32(i->Aux.WeakExternal.Characteristics);
570 WriteZeros(
sizeof(i->Aux.WeakExternal.unused));
573 WriteBytes(
StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName),
574 sizeof(i->Aux.File.FileName)));
576 case ATSectionDefinition:
577 WriteLE32(i->Aux.SectionDefinition.Length);
578 WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations);
579 WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers);
580 WriteLE32(i->Aux.SectionDefinition.CheckSum);
581 WriteLE16(i->Aux.SectionDefinition.Number);
582 Write8(i->Aux.SectionDefinition.Selection);
583 WriteZeros(
sizeof(i->Aux.SectionDefinition.unused));
589 void WinCOFFObjectWriter::WriteSectionHeader(
const COFF::section &S) {
612 void WinCOFFObjectWriter::ExecutePostLayoutBinding(
MCAssembler &Asm,
623 if (ExportSymbol(*i, Asm)) {
624 DefineSymbol(*i, Asm, Layout);
629 void WinCOFFObjectWriter::RecordRelocation(
const MCAssembler &Asm,
634 uint64_t &FixedValue) {
635 assert(Target.
getSymA() != NULL &&
"Relocation must reference a symbol!");
638 const MCSymbol &
A = Symbol.AliasedSymbol();
644 assert(SectionMap.find(&SectionData->
getSection()) != SectionMap.end() &&
645 "Section must already have been defined in ExecutePostLayoutBinding!");
646 assert(SymbolMap.find(&A_SD.
getSymbol()) != SymbolMap.end() &&
647 "Symbol must already have been defined in ExecutePostLayoutBinding!");
649 COFFSection *coff_section = SectionMap[&SectionData->
getSection()];
650 COFFSymbol *coff_symbol = SymbolMap[&A_SD.
getSymbol()];
653 const bool CrossSection = SymB &&
676 COFFRelocation Reloc;
678 Reloc.Data.SymbolTableIndex = 0;
682 if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) {
683 Reloc.Symb = coff_symbol->Section->Symbol;
685 + coff_symbol->MCData->getOffset();
687 Reloc.Symb = coff_symbol;
689 ++Reloc.Symb->Relocations;
691 Reloc.Data.VirtualAddress += Fixup.
getOffset();
692 Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup,
701 coff_section->Relocations.push_back(Reloc);
704 void WinCOFFObjectWriter::WriteObject(
MCAssembler &Asm,
707 Header.NumberOfSections = 0;
710 for (sections::iterator i = Sections.begin(),
711 e = Sections.end(); i != e; i++) {
713 size_t Number = ++Header.NumberOfSections;
714 SectionIndices[*i] = Number;
715 MakeSectionReal(**i, Number);
721 Header.NumberOfSymbols = 0;
723 for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) {
724 COFFSymbol *coff_symbol = *i;
728 if ((SymbolData != NULL) && (SymbolData->
Fragment != NULL)) {
729 assert(coff_symbol->Section != NULL);
731 coff_symbol->Data.SectionNumber = coff_symbol->Section->Number;
736 if (coff_symbol->should_keep()) {
737 MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++);
740 coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size();
741 Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols;
743 coff_symbol->Index = -1;
747 for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) {
748 COFFSymbol *coff_symbol = *i;
749 if (coff_symbol->Other != NULL) {
750 assert(coff_symbol->Index != -1);
751 assert(coff_symbol->Aux.size() == 1 &&
752 "Symbol must contain one aux symbol!");
753 assert(coff_symbol->Aux[0].AuxType == ATWeakExternal &&
754 "Symbol's aux symbol must be a Weak External!");
755 coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index;
760 for (sections::iterator i = Sections.begin(),
761 e = Sections.end(); i != e; i++) {
762 if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
767 (*i)->MCData->getSection());
777 if (Assoc->Number == -1)
780 (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc];
794 COFFSection *Sec = SectionMap[&i->getSection()];
796 if (Sec->Number == -1)
801 if (IsPhysicalSection(Sec)) {
802 Sec->Header.PointerToRawData = offset;
804 offset += Sec->Header.SizeOfRawData;
807 if (Sec->Relocations.size() > 0) {
808 bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
810 if (RelocationsOverflow) {
813 Sec->Header.NumberOfRelocations = 0xffff;
815 Sec->Header.NumberOfRelocations = Sec->Relocations.size();
817 Sec->Header.PointerToRelocations = offset;
819 if (RelocationsOverflow) {
826 for (relocations::iterator cr = Sec->Relocations.begin(),
827 er = Sec->Relocations.end();
829 assert((*cr).Symb->Index != -1);
830 (*cr).Data.SymbolTableIndex = (*cr).Symb->Index;
834 assert(Sec->Symbol->Aux.size() == 1
835 &&
"Section's symbol must have one aux!");
836 AuxSymbol &Aux = Sec->Symbol->Aux[0];
837 assert(Aux.AuxType == ATSectionDefinition &&
838 "Section's symbol's aux symbol must be a Section Definition!");
839 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
840 Aux.Aux.SectionDefinition.NumberOfRelocations =
841 Sec->Header.NumberOfRelocations;
842 Aux.Aux.SectionDefinition.NumberOfLinenumbers =
843 Sec->Header.NumberOfLineNumbers;
846 Header.PointerToSymbolTable = offset;
848 Header.TimeDateStamp = sys::TimeValue::now().toEpochTime();
851 WriteFileHeader(Header);
854 sections::iterator i, ie;
857 for (i = Sections.begin(), ie = Sections.end(); i != ie; i++)
858 if ((*i)->Number != -1) {
859 if ((*i)->Relocations.size() >= 0xffff) {
860 (*i)->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
862 WriteSectionHeader((*i)->Header);
865 for (i = Sections.begin(), ie = Sections.end(),
867 (i != ie) && (j != je); ++i, ++j) {
869 if ((*i)->Number == -1)
872 if ((*i)->Header.PointerToRawData != 0) {
873 assert(OS.
tell() == (*i)->Header.PointerToRawData &&
874 "Section::PointerToRawData is insane!");
879 if ((*i)->Relocations.size() > 0) {
880 assert(OS.
tell() == (*i)->Header.PointerToRelocations &&
881 "Section::PointerToRelocations is insane!");
883 if ((*i)->Relocations.size() >= 0xffff) {
893 for (relocations::const_iterator k = (*i)->Relocations.begin(),
894 ke = (*i)->Relocations.end();
896 WriteRelocation(k->Data);
899 assert((*i)->Header.PointerToRelocations == 0 &&
900 "Section::PointerToRelocations is insane!");
904 assert(OS.
tell() == Header.PointerToSymbolTable &&
905 "Header::PointerToSymbolTable is insane!");
907 for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++)
908 if ((*i)->Index != -1)
911 OS.
write((
char const *)&Strings.Data.front(), Strings.Data.size());
914 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(
unsigned Machine_) :
919 void MCWinCOFFObjectTargetWriter::anchor() {}
927 return new WinCOFFObjectWriter(MOTW, OS);
const_iterator end(StringRef path)
Get end iterator over path.
int sprintf(char *str, const char *format, ...);
const MCSymbol & getSymbol() const
SectionVariant getVariant() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
std::string str() const
str - Get the contents as an std::string.
const_iterator begin(StringRef path)
Get begin iterator over path.
uint8_t MCData
An entry in an MCDataAtom.
const MCSymbol & getSymbol() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
symbol_iterator symbol_begin()
MCObjectWriter * createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS)
Construct a new Win COFF writer instance.
MCSectionCOFF - This represents a section on Windows.
const MCSection & getSection() const
#define llvm_unreachable(msg)
const MCExpr * getVariableValue() const
getVariableValue() - Get the value for variable symbols.
uint64_t tell() const
tell - Return the current offset with the file.
static void write_uint32_le(void *Data, uint32_t const &Value)
COFF::MachineTypes Machine
const MCSection & getSection() const
uint32_t getOffset() const
uint32_t SymbolTableIndex
const MCSectionCOFF * getAssocSection() const
* if(!EatIfPresent(lltok::kw_thread_local)) return false
MCSectionData * getParent() const
uint32_t getFlags() const
getFlags - Get the (implementation defined) symbol flags.
MCFragment * Fragment
Fragment - The fragment this symbol's value is relative to, if any.
const MCSymbolRefExpr * getSymB() const
bool isAbsolute() const
isAbsolute - Check if this is an absolute symbol.
uint16_t NumberOfLineNumbers
raw_ostream & write(unsigned char C)
MCSymbolData & getSymbolData(const MCSymbol &Symbol) const
uint32_t PointerToRelocations
const MCSymbolRefExpr * getSymA() const
StringRef getSectionName() const
unsigned getAlignment() const
uint32_t PointerToRawData
uint64_t getSymbolOffset(const MCSymbolData *SD) const
Get the offset of the given symbol, as computed in the current layout.
uint64_t getSectionAddressSize(const MCSectionData *SD) const
Get the address space size of the given section, as it effects layout. This may differ from the size ...
StringRef getName() const
getName - Get the symbol name.
const MCSymbol & AliasedSymbol() const
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
bool isVariable() const
isVariable - Check if this is a variable symbol.
uint16_t NumberOfRelocations
int64_t getConstant() const
LLVM Value Representation.
void writeSectionData(const MCSectionData *Section, const MCAsmLayout &Layout) const
Emit the section contents using the given object writer.
uint32_t PointerToLineNumbers
COFF::SectionCharacteristics Characteristics
symbol_iterator symbol_end()