diff options
-rw-r--r-- | lib/MC/WinCOFFObjectWriter.cpp | 245 | ||||
-rw-r--r-- | test/MC/COFF/basic-coff.ll | 38 | ||||
-rw-r--r-- | test/MC/COFF/symbol-fragment-offset.ll | 56 |
3 files changed, 196 insertions, 143 deletions
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index eeb2b9675f..d686098faa 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -55,6 +55,9 @@ struct AuxSymbol { COFF::Auxiliary Aux; }; +class COFFSymbol; +class COFFSection; + class COFFSymbol { public: COFF::symbol Data; @@ -65,12 +68,16 @@ public: size_t Index; AuxiliarySymbols Aux; COFFSymbol *Other; + COFFSection *Section; + int Relocations; MCSymbolData const *MCData; - COFFSymbol(llvm::StringRef name, size_t index); + COFFSymbol(llvm::StringRef name); size_t size() const; void set_name_offset(uint32_t Offset); + + bool should_keep() const; }; // This class contains staging data for a COFF relocation entry. @@ -91,10 +98,10 @@ public: std::string Name; size_t Number; MCSectionData const *MCData; - COFFSymbol *Symb; + COFFSymbol *Symbol; relocations Relocations; - COFFSection(llvm::StringRef name, size_t Index); + COFFSection(llvm::StringRef name); static size_t size(); }; @@ -141,18 +148,20 @@ public: COFFSymbol *createSymbol(llvm::StringRef Name); COFFSection *createSection(llvm::StringRef Name); - void InitCOFFEntity(COFFSymbol &Symbol); - void InitCOFFEntity(COFFSection &Section); - template <typename object_t, typename list_t> object_t *createCOFFEntity(llvm::StringRef Name, list_t &List); void DefineSection(MCSectionData const &SectionData); void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler); - bool ExportSection(COFFSection *S); + void MakeSymbolReal(COFFSymbol &S, size_t Index); + void MakeSectionReal(COFFSection &S, size_t Number); + + bool ExportSection(COFFSection const *S); bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm); + bool IsPhysicalSection(COFFSection *S); + // Entity writing methods. void WriteFileHeader(const COFF::header &Header); @@ -198,9 +207,12 @@ static inline void write_uint8_le(void *Data, uint8_t const &Value) { //------------------------------------------------------------------------------ // Symbol class implementation -COFFSymbol::COFFSymbol(llvm::StringRef name, size_t index) - : Name(name.begin(), name.end()), Index(-1) - , Other(NULL), MCData(NULL) { +COFFSymbol::COFFSymbol(llvm::StringRef name) + : Name(name.begin(), name.end()) + , Other(NULL) + , Section(NULL) + , Relocations(0) + , MCData(NULL) { memset(&Data, 0, sizeof(Data)); } @@ -216,12 +228,41 @@ void COFFSymbol::set_name_offset(uint32_t Offset) { write_uint32_le(Data.Name + 4, Offset); } +/// logic to decide if the symbol should be reported in the symbol table +bool COFFSymbol::should_keep() const { + // no section means its external, keep it + if (Section == NULL) + return true; + + // if it has relocations pointing at it, keep it + if (Relocations > 0) { + assert(Section->Number != -1 && "Sections with relocations must be real!"); + return true; + } + + // if the section its in is being droped, drop it + if (Section->Number == -1) + return false; + + // if it is the section symbol, keep it + if (Section->Symbol == this) + return true; + + // if its temporary, drop it + if (MCData && MCData->getSymbol().isTemporary()) + return false; + + // otherwise, keep it + return true; +} + //------------------------------------------------------------------------------ // Section class implementation -COFFSection::COFFSection(llvm::StringRef name, size_t Index) - : Name(name), Number(Index + 1) - , MCData(NULL), Symb(NULL) { +COFFSection::COFFSection(llvm::StringRef name) + : Name(name) + , MCData(NULL) + , Symbol(NULL) { memset(&Header, 0, sizeof(Header)); } @@ -298,45 +339,12 @@ COFFSection *WinCOFFObjectWriter::createSection(llvm::StringRef Name) { return createCOFFEntity<COFFSection>(Name, Sections); } -/// This function initializes a symbol by entering its name into the string -/// table if it is too long to fit in the symbol table header. -void WinCOFFObjectWriter::InitCOFFEntity(COFFSymbol &S) { - if (S.Name.size() > COFF::NameSize) { - size_t StringTableEntry = Strings.insert(S.Name.c_str()); - - S.set_name_offset(StringTableEntry); - } else - memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); -} - -/// This function initializes a section by entering its name into the string -/// table if it is too long to fit in the section table header. -void WinCOFFObjectWriter::InitCOFFEntity(COFFSection &S) { - if (S.Name.size() > COFF::NameSize) { - size_t StringTableEntry = Strings.insert(S.Name.c_str()); - - // FIXME: Why is this number 999999? This number is never mentioned in the - // spec. I'm assuming this is due to the printed value needing to fit into - // the S.Header.Name field. In which case why not 9999999 (7 9's instead of - // 6)? The spec does not state if this entry should be null terminated in - // this case, and thus this seems to be the best way to do it. I think I - // just solved my own FIXME... - if (StringTableEntry > 999999) - report_fatal_error("COFF string table is greater than 999999 bytes."); - - sprintf(S.Header.Name, "/%d", (unsigned)StringTableEntry); - } else - memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); -} - /// A template used to lookup or create a symbol/section, and initialize it if /// needed. template <typename object_t, typename list_t> object_t *WinCOFFObjectWriter::createCOFFEntity(llvm::StringRef Name, list_t &List) { - object_t *Object = new object_t(Name, List.size()); - - InitCOFFEntity(*Object); + object_t *Object = new object_t(Name); List.push_back(Object); @@ -353,15 +361,14 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { COFFSection *coff_section = createSection(Sec.getSectionName()); COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); - coff_section->Symb = coff_symbol; + coff_section->Symbol = coff_symbol; + coff_symbol->Section = coff_section; coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; - coff_symbol->Data.SectionNumber = coff_section->Number; // In this case the auxiliary symbol is a Section Definition. coff_symbol->Aux.resize(1); memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); coff_symbol->Aux[0].AuxType = ATSectionDefinition; - coff_symbol->Aux[0].Aux.SectionDefinition.Number = coff_section->Number; coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection(); coff_section->Header.Characteristics = Sec.getCharacteristics(); @@ -394,7 +401,9 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { /// This function takes a section data object from the assembler /// and creates the associated COFF symbol staging object. void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, - MCAssembler &Assembler) { + MCAssembler &Assembler) { + assert(!SymbolData.getSymbol().isVariable() + && "Cannot define a symbol that is a variable!"); COFFSymbol *coff_symbol = createSymbol(SymbolData.getSymbol().getName()); coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0; @@ -405,7 +414,7 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, bool external = SymbolData.isExternal() || (SymbolData.Fragment == NULL); coff_symbol->Data.StorageClass = - external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; + external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_LABEL; } if (SymbolData.getFlags() & COFF::SF_WeakReference) { @@ -438,14 +447,50 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; } + if (SymbolData.Fragment != NULL) + coff_symbol->Section = SectionMap[SymbolData.Fragment->getParent()]; + // Bind internal COFF symbol to MC symbol. coff_symbol->MCData = &SymbolData; SymbolMap[&SymbolData] = coff_symbol; } -bool WinCOFFObjectWriter::ExportSection(COFFSection *S) { - return (S->Header.Characteristics - & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0; +/// making a section real involves assigned it a number and putting +/// name into the string table if needed +void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) { + if (S.Name.size() > COFF::NameSize) { + size_t StringTableEntry = Strings.insert(S.Name.c_str()); + + // FIXME: Why is this number 999999? This number is never mentioned in the + // spec. I'm assuming this is due to the printed value needing to fit into + // the S.Header.Name field. In which case why not 9999999 (7 9's instead of + // 6)? The spec does not state if this entry should be null terminated in + // this case, and thus this seems to be the best way to do it. I think I + // just solved my own FIXME... + if (StringTableEntry > 999999) + report_fatal_error("COFF string table is greater than 999999 bytes."); + + std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry)); + } else + std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); + + S.Number = Number; + S.Symbol->Data.SectionNumber = S.Number; + S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number; +} + +void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) { + if (S.Name.size() > COFF::NameSize) { + size_t StringTableEntry = Strings.insert(S.Name.c_str()); + + S.set_name_offset(StringTableEntry); + } else + std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); + S.Index = Index; +} + +bool WinCOFFObjectWriter::ExportSection(COFFSection const *S) { + return !S->MCData->getFragmentList().empty(); } bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData, @@ -455,8 +500,14 @@ bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData, // return Asm.isSymbolLinkerVisible (&SymbolData); - // For now, all symbols are exported, the linker will sort it out for us. - return true; + // For now, all non-variable symbols are exported, + // the linker will sort the rest out for us. + return !SymbolData.getSymbol().isVariable(); +} + +bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { + return (S->Header.Characteristics + & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0; } //------------------------------------------------------------------------------ @@ -548,7 +599,7 @@ void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { // "Define" each section & symbol. This creates section & symbol - // entries in the staging area and gives them their final indexes. + // entries in the staging area. for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++) DefineSection(*i); @@ -600,7 +651,15 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, Reloc.Data.SymbolTableIndex = 0; Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); - Reloc.Symb = coff_symbol; + + // turn relocations for temporary symbols into section relocations + if (coff_symbol->MCData->getSymbol().isTemporary()) { + Reloc.Symb = coff_symbol->Section->Symbol; + FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment); + } else + Reloc.Symb = coff_symbol; + + ++Reloc.Symb->Relocations; Reloc.Data.VirtualAddress += Fixup.getOffset(); @@ -634,6 +693,16 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout) { // Assign symbol and section indexes and offsets. + Header.NumberOfSections = 0; + + for (sections::iterator i = Sections.begin(), + e = Sections.end(); i != e; i++) { + if (Layout.getSectionSize((*i)->MCData) > 0) { + MakeSectionReal(**i, ++Header.NumberOfSections); + } else { + (*i)->Number = -1; + } + } Header.NumberOfSymbols = 0; @@ -641,32 +710,35 @@ void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm, COFFSymbol *coff_symbol = *i; MCSymbolData const *SymbolData = coff_symbol->MCData; - coff_symbol->Index = Header.NumberOfSymbols++; - // Update section number & offset for symbols that have them. if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) { - COFFSection *coff_section = SectionMap[SymbolData->Fragment->getParent()]; + assert(coff_symbol->Section != NULL); - coff_symbol->Data.SectionNumber = coff_section->Number; + coff_symbol->Data.SectionNumber = coff_symbol->Section->Number; coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment) + SymbolData->Offset; } - // Update auxiliary symbol info. - coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size(); - Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols; + if (coff_symbol->should_keep()) { + MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++); + + // Update auxiliary symbol info. + coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size(); + Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols; + } else + coff_symbol->Index = -1; } // Fixup weak external references. for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { - COFFSymbol *symb = *i; - - if (symb->Other != NULL) { - assert(symb->Aux.size() == 1 && + COFFSymbol *coff_symbol = *i; + if (coff_symbol->Other != NULL) { + assert(coff_symbol->Index != -1); + assert(coff_symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!"); - assert(symb->Aux[0].AuxType == ATWeakExternal && + assert(coff_symbol->Aux[0].AuxType == ATWeakExternal && "Symbol's aux symbol must be a Weak External!"); - symb->Aux[0].Aux.WeakExternal.TagIndex = symb->Other->Index; + coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index; } } @@ -675,18 +747,19 @@ void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm, unsigned offset = 0; offset += COFF::HeaderSize; - offset += COFF::SectionSize * Asm.size(); - - Header.NumberOfSections = Sections.size(); + offset += COFF::SectionSize * Header.NumberOfSections; for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++) { COFFSection *Sec = SectionMap[i]; + if (Sec->Number == -1) + continue; + Sec->Header.SizeOfRawData = Layout.getSectionFileSize(i); - if (ExportSection(Sec)) { + if (IsPhysicalSection(Sec)) { Sec->Header.PointerToRawData = offset; offset += Sec->Header.SizeOfRawData; @@ -700,13 +773,15 @@ void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm, for (relocations::iterator cr = Sec->Relocations.begin(), er = Sec->Relocations.end(); - cr != er; cr++) { + cr != er; ++cr) { + assert((*cr).Symb->Index != -1); (*cr).Data.SymbolTableIndex = (*cr).Symb->Index; } } - assert(Sec->Symb->Aux.size() == 1 && "Section's symbol must have one aux!"); - AuxSymbol &Aux = Sec->Symb->Aux[0]; + assert(Sec->Symbol->Aux.size() == 1 + && "Section's symbol must have one aux!"); + AuxSymbol &Aux = Sec->Symbol->Aux[0]; assert(Aux.AuxType == ATSectionDefinition && "Section's symbol's aux symbol must be a Section Definition!"); Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; @@ -728,11 +803,16 @@ void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm, MCAssembler::const_iterator j, je; for (i = Sections.begin(), ie = Sections.end(); i != ie; i++) - WriteSectionHeader((*i)->Header); + if ((*i)->Number != -1) + WriteSectionHeader((*i)->Header); for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(), je = Asm.end(); - (i != ie) && (j != je); i++, j++) { + (i != ie) && (j != je); ++i, ++j) { + + if ((*i)->Number == -1) + continue; + if ((*i)->Header.PointerToRawData != 0) { assert(OS.tell() == (*i)->Header.PointerToRawData && "Section::PointerToRawData is insane!"); @@ -759,7 +839,8 @@ void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm, "Header::PointerToSymbolTable is insane!"); for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) - WriteSymbol(*i); + if ((*i)->Index != -1) + WriteSymbol(*i); OS.write((char const *)&Strings.Data.front(), Strings.Data.size()); } diff --git a/test/MC/COFF/basic-coff.ll b/test/MC/COFF/basic-coff.ll index f2ffc168ac..1452934c5d 100644 --- a/test/MC/COFF/basic-coff.ll +++ b/test/MC/COFF/basic-coff.ll @@ -19,8 +19,8 @@ declare i32 @printf(i8* nocapture, ...) nounwind ; CHECK: MachineType = IMAGE_FILE_MACHINE_I386 (0x14C) ; CHECK: NumberOfSections = 2 ; CHECK: TimeDateStamp = {{[0-9]+}} -; CHECK: PointerToSymbolTable = 0x99 -; CHECK: NumberOfSymbols = 7 +; CHECK: PointerToSymbolTable = 0x{{[0-9A-F]+}} +; CHECK: NumberOfSymbols = 6 ; CHECK: SizeOfOptionalHeader = 0 ; CHECK: Characteristics = 0x0 ; CHECK: Sections = [ @@ -28,9 +28,9 @@ declare i32 @printf(i8* nocapture, ...) nounwind ; CHECK: Name = .text ; CHECK: VirtualSize = 0 ; CHECK: VirtualAddress = 0 -; CHECK: SizeOfRawData = 21 -; CHECK: PointerToRawData = 0x64 -; CHECK: PointerToRelocations = 0x79 +; CHECK: SizeOfRawData = {{[0-9]+}} +; CHECK: PointerToRawData = 0x{{[0-9A-F]+}} +; CHECK: PointerToRelocations = 0x{{[0-9A-F]+}} ; CHECK: PointerToLineNumbers = 0x0 ; CHECK: NumberOfRelocations = 2 ; CHECK: NumberOfLineNumbers = 0 @@ -40,20 +40,18 @@ declare i32 @printf(i8* nocapture, ...) nounwind ; CHECK: IMAGE_SCN_MEM_EXECUTE ; CHECK: IMAGE_SCN_MEM_READ ; CHECK: SectionData = -; CHECK: 83 EC 04 C7 04 24 00 00 - 00 00 E8 00 00 00 00 31 |.....$.........1| -; CHECK: C0 83 C4 04 C3 |.....| ; CHECK: Relocations = [ ; CHECK: 0 = { -; CHECK: VirtualAddress = 0x6 -; CHECK: SymbolTableIndex = 5 +; CHECK: VirtualAddress = 0x{{[0-9A-F]+}} +; CHECK: SymbolTableIndex = 2 ; CHECK: Type = IMAGE_REL_I386_DIR32 (6) -; CHECK: SymbolName = _main +; CHECK: SymbolName = ; CHECK: } ; CHECK: 1 = { -; CHECK: VirtualAddress = 0xB -; CHECK: SymbolTableIndex = 6 +; CHECK: VirtualAddress = 0x{{[0-9A-F]+}} +; CHECK: SymbolTableIndex = 5 ; CHECK: Type = IMAGE_REL_I386_REL32 (20) -; CHECK: SymbolName = L_.str +; CHECK: SymbolName = _main ; CHECK: } ; CHECK: ] ; CHECK: } @@ -61,8 +59,8 @@ declare i32 @printf(i8* nocapture, ...) nounwind ; CHECK: Name = .data ; CHECK: VirtualSize = 0 ; CHECK: VirtualAddress = 0 -; CHECK: SizeOfRawData = 12 -; CHECK: PointerToRawData = 0x8D +; CHECK: SizeOfRawData = {{[0-9]+}} +; CHECK: PointerToRawData = 0x{{[0-9A-F]+}} ; CHECK: PointerToRelocations = 0x0 ; CHECK: PointerToLineNumbers = 0x0 ; CHECK: NumberOfRelocations = 0 @@ -113,16 +111,6 @@ declare i32 @printf(i8* nocapture, ...) nounwind ; CHECK: AuxillaryData = ; CHECK: } ; CHECK: 3 = { -; CHECK: Name = L_.str -; CHECK: Value = 0 -; CHECK: SectionNumber = 2 -; CHECK: SimpleType = IMAGE_SYM_TYPE_NULL (0) -; CHECK: ComplexType = IMAGE_SYM_DTYPE_NULL (0) -; CHECK: StorageClass = IMAGE_SYM_CLASS_STATIC (3) -; CHECK: NumberOfAuxSymbols = 0 -; CHECK: AuxillaryData = -; CHECK: } -; CHECK: 4 = { ; CHECK: Name = _printf ; CHECK: Value = 0 ; CHECK: SectionNumber = 0 diff --git a/test/MC/COFF/symbol-fragment-offset.ll b/test/MC/COFF/symbol-fragment-offset.ll index 4281903f25..f1f31a94cf 100644 --- a/test/MC/COFF/symbol-fragment-offset.ll +++ b/test/MC/COFF/symbol-fragment-offset.ll @@ -23,8 +23,8 @@ declare i32 @puts(i8* nocapture) nounwind ; CHECK: MachineType = IMAGE_FILE_MACHINE_I386 (0x14C)
; CHECK: NumberOfSections = 2
; CHECK: TimeDateStamp = {{[0-9]+}}
-; CHECK: PointerToSymbolTable = 0xBB
-; CHECK: NumberOfSymbols = 9
+; CHECK: PointerToSymbolTable = 0x{{[0-9A-F]+}}
+; CHECK: NumberOfSymbols = 8
; CHECK: SizeOfOptionalHeader = 0
; CHECK: Characteristics = 0x0
; CHECK: Sections = [
@@ -32,9 +32,9 @@ declare i32 @puts(i8* nocapture) nounwind ; CHECK: Name = .text
; CHECK: VirtualSize = 0
; CHECK: VirtualAddress = 0
-; CHECK: SizeOfRawData = 33
-; CHECK: PointerToRawData = 0x64
-; CHECK: PointerToRelocations = 0x85
+; CHECK: SizeOfRawData = {{[0-9]+}}
+; CHECK: PointerToRawData = 0x{{[0-9A-F]+}}
+; CHECK: PointerToRelocations = 0x{{[0-9A-F]+}}
; CHECK: PointerToLineNumbers = 0x0
; CHECK: NumberOfRelocations = 4
; CHECK: NumberOfLineNumbers = 0
@@ -44,32 +44,28 @@ declare i32 @puts(i8* nocapture) nounwind ; CHECK: IMAGE_SCN_MEM_EXECUTE
; CHECK: IMAGE_SCN_MEM_READ
; CHECK: SectionData =
-; CHECK: 83 EC 04 C7 04 24 00 00 - 00 00 E8 00 00 00 00 C7 |.....$..........|
-; CHECK: 04 24 00 00 00 00 E8 00 - 00 00 00 31 C0 83 C4 04 |.$.........1....|
-; CHECK: C3 |.|
-
; CHECK: Relocations = [
; CHECK: 0 = {
-; CHECK: VirtualAddress = 0x6
-; CHECK: SymbolTableIndex = 5
+; CHECK: VirtualAddress = 0x{{[0-9A-F]+}}
+; CHECK: SymbolTableIndex = 2
; CHECK: Type = IMAGE_REL_I386_DIR32 (6)
-; CHECK: SymbolName = _main
+; CHECK: SymbolName =
; CHECK: }
; CHECK: 1 = {
-; CHECK: VirtualAddress = 0xB
-; CHECK: SymbolTableIndex = 6
+; CHECK: VirtualAddress = 0x{{[0-9A-F]+}}
+; CHECK: SymbolTableIndex = 5
; CHECK: Type = IMAGE_REL_I386_REL32 (20)
-; CHECK: SymbolName = L_.str
+; CHECK: SymbolName = _main
; CHECK: }
; CHECK: 2 = {
-; CHECK: VirtualAddress = 0x12
-; CHECK: SymbolTableIndex = 7
+; CHECK: VirtualAddress = 0x{{[0-9A-F]+}}
+; CHECK: SymbolTableIndex = 6
; CHECK: Type = IMAGE_REL_I386_DIR32 (6)
; CHECK: SymbolName = _printf
; CHECK: }
; CHECK: 3 = {
-; CHECK: VirtualAddress = 0x17
-; CHECK: SymbolTableIndex = 8
+; CHECK: VirtualAddress = 0x{{[0-9A-F]+}}
+; CHECK: SymbolTableIndex = 7
; CHECK: Type = IMAGE_REL_I386_REL32 (20)
; CHECK: SymbolName = _str
; CHECK: }
@@ -79,8 +75,8 @@ declare i32 @puts(i8* nocapture) nounwind ; CHECK: Name = .data
; CHECK: VirtualSize = 0
; CHECK: VirtualAddress = 0
-; CHECK: SizeOfRawData = 14
-; CHECK: PointerToRawData = 0xAD
+; CHECK: SizeOfRawData = {{[0-9]+}}
+; CHECK: PointerToRawData = 0x{{[0-9A-F]+}}
; CHECK: PointerToRelocations = 0x0
; CHECK: PointerToLineNumbers = 0x0
; CHECK: NumberOfRelocations = 0
@@ -133,19 +129,7 @@ declare i32 @puts(i8* nocapture) nounwind ; CHECK: NumberOfAuxSymbols = 0
; CHECK: AuxillaryData =
-; CHECK: }
; CHECK: 3 = {
-; CHECK: Name = L_.str
-; CHECK: Value = 0
-; CHECK: SectionNumber = 2
-; CHECK: SimpleType = IMAGE_SYM_TYPE_NULL (0)
-; CHECK: ComplexType = IMAGE_SYM_DTYPE_NULL (0)
-; CHECK: StorageClass = IMAGE_SYM_CLASS_STATIC (3)
-; CHECK: NumberOfAuxSymbols = 0
-; CHECK: AuxillaryData =
-
-; CHECK: }
-; CHECK: 4 = {
; CHECK: Name = _printf
; CHECK: Value = 0
; CHECK: SectionNumber = 0
@@ -156,18 +140,18 @@ declare i32 @puts(i8* nocapture) nounwind ; CHECK: AuxillaryData =
; CHECK: }
-; CHECK: 5 = {
+; CHECK: 4 = {
; CHECK: Name = _str
; CHECK: Value = 7
; CHECK: SectionNumber = 2
; CHECK: SimpleType = IMAGE_SYM_TYPE_NULL (0)
; CHECK: ComplexType = IMAGE_SYM_DTYPE_NULL (0)
-; CHECK: StorageClass = IMAGE_SYM_CLASS_STATIC (3)
+; CHECK: StorageClass = IMAGE_SYM_CLASS_LABEL (6)
; CHECK: NumberOfAuxSymbols = 0
; CHECK: AuxillaryData =
; CHECK: }
-; CHECK: 6 = {
+; CHECK: 5 = {
; CHECK: Name = _puts
; CHECK: Value = 0
; CHECK: SectionNumber = 0
|