X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FMC%2FWinCOFFObjectWriter.cpp;h=824895be32de851e30dbdb56a71f94827a75a59e;hb=0e9c68e6bc8768143308b0162e900ba8bd10dc01;hp=fc0d51ca076fe0d7356b8a9442163e87bc8341a4;hpb=1c5e4e50211ad2a8024c28fa0237a8026ba51f8f;p=oota-llvm.git diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index fc0d51ca076..824895be32d 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -153,7 +153,7 @@ public: void MakeSymbolReal(COFFSymbol &S, size_t Index); void MakeSectionReal(COFFSection &S, size_t Number); - bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm); + bool ExportSymbol(const MCSymbol &Symbol, MCAssembler &Asm); bool IsPhysicalSection(COFFSection *S); @@ -347,6 +347,14 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { COFFSection *coff_section = createSection(Sec.getSectionName()); COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); + if (Sec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { + if (const MCSymbol *S = Sec.getCOMDATSymbol()) { + COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S); + if (COMDATSymbol->Section) + report_fatal_error("two sections have the same comdat"); + COMDATSymbol->Section = coff_section; + } + } coff_section->Symbol = coff_symbol; coff_symbol->Section = coff_section; @@ -385,6 +393,18 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { SectionMap[&SectionData.getSection()] = coff_section; } +static uint64_t getSymbolValue(const MCSymbolData &Data, + const MCAsmLayout &Layout) { + if (Data.isCommon() && Data.isExternal()) + return Data.getCommonSize(); + + uint64_t Res; + if (!Layout.getSymbolOffset(&Data, Res)) + return 0; + + return Res; +} + /// This function takes a symbol data object from the assembler /// and creates the associated COFF symbol staging object. void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, @@ -427,33 +447,38 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, coff_symbol->MCData = &SymbolData; } else { - const MCSymbolData &ResSymData = - Assembler.getSymbolData(Symbol.AliasedSymbol()); - - if (Symbol.isVariable()) { - int64_t Addr; - if (Symbol.getVariableValue()->EvaluateAsAbsolute(Addr, Layout)) - coff_symbol->Data.Value = Addr; - } else if (SymbolData.isExternal() && SymbolData.isCommon()) { - coff_symbol->Data.Value = SymbolData.getCommonSize(); - } + const MCSymbolData &ResSymData = Assembler.getSymbolData(Symbol); + const MCSymbol *Base = Layout.getBaseSymbol(Symbol); + coff_symbol->Data.Value = getSymbolValue(ResSymData, Layout); coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0; coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16; // If no storage class was specified in the streamer, define it here. if (coff_symbol->Data.StorageClass == 0) { - bool external = ResSymData.isExternal() || !ResSymData.Fragment; + bool IsExternal = + ResSymData.isExternal() || + (!ResSymData.getFragment() && !ResSymData.getSymbol().isVariable()); - coff_symbol->Data.StorageClass = - external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; + coff_symbol->Data.StorageClass = IsExternal + ? COFF::IMAGE_SYM_CLASS_EXTERNAL + : COFF::IMAGE_SYM_CLASS_STATIC; } - if (Symbol.isAbsolute() || Symbol.AliasedSymbol().isVariable()) + if (!Base) { coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; - else if (ResSymData.Fragment) - coff_symbol->Section = - SectionMap[&ResSymData.Fragment->getParent()->getSection()]; + } else { + const MCSymbolData &BaseData = Assembler.getSymbolData(*Base); + if (BaseData.Fragment) { + COFFSection *Sec = + SectionMap[&BaseData.Fragment->getParent()->getSection()]; + + if (coff_symbol->Section && coff_symbol->Section != Sec) + report_fatal_error("conflicting sections for symbol"); + + coff_symbol->Section = Sec; + } + } coff_symbol->MCData = &ResSymData; } @@ -524,16 +549,24 @@ void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) { S.Index = Index; } -bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData, +bool WinCOFFObjectWriter::ExportSymbol(const MCSymbol &Symbol, MCAssembler &Asm) { // This doesn't seem to be right. Strings referred to from the .data section // need symbols so they can be linked to code in the .text section right? - // return Asm.isSymbolLinkerVisible (&SymbolData); + // return Asm.isSymbolLinkerVisible(Symbol); + + // Non-temporary labels should always be visible to the linker. + if (!Symbol.isTemporary()) + return true; + + // Absolute temporary labels are never visible. + if (!Symbol.isInSection()) + return false; // For now, all non-variable symbols are exported, // the linker will sort the rest out for us. - return SymbolData.isExternal() || !SymbolData.getSymbol().isVariable(); + return !Symbol.isVariable(); } bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { @@ -641,6 +674,7 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, unsigned Count = (FI->size() + COFF::SymbolSize - 1) / COFF::SymbolSize; COFFSymbol *file = createSymbol(".file"); + file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG; file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE; file->Aux.resize(Count); @@ -666,7 +700,7 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, DefineSection(Section); for (MCSymbolData &SD : Asm.symbols()) - if (ExportSymbol(SD, Asm)) + if (ExportSymbol(SD.getSymbol(), Asm)) DefineSymbol(SD, Asm, Layout); } @@ -780,7 +814,7 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, case COFF::IMAGE_REL_ARM_MOV32A: // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are // only used for ARM mode code, which is documented as being unsupported - // by Windows on ARM. Emperical proof indicates that masm is able to + // by Windows on ARM. Empirical proof indicates that masm is able to // generate the relocations however the rest of the MSVC toolchain is // unable to handle it. llvm_unreachable("unsupported relocation"); @@ -799,7 +833,8 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, } } - coff_section->Relocations.push_back(Reloc); + if (TargetObjectWriter->recordRelocation(Fixup)) + coff_section->Relocations.push_back(Reloc); } void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, @@ -809,28 +844,17 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, DenseMap SectionIndices; for (auto & Section : Sections) { - if (Layout.getSectionAddressSize(Section->MCData) > 0) { - size_t Number = ++Header.NumberOfSections; - SectionIndices[Section.get()] = Number; - MakeSectionReal(*Section, Number); - } else { - Section->Number = -1; - } + size_t Number = ++Header.NumberOfSections; + SectionIndices[Section.get()] = Number; + MakeSectionReal(*Section, Number); } Header.NumberOfSymbols = 0; for (auto & Symbol : Symbols) { - MCSymbolData const *SymbolData = Symbol->MCData; - // Update section number & offset for symbols that have them. - if (SymbolData && SymbolData->Fragment) { - assert(Symbol->Section != nullptr); - + if (Symbol->Section) Symbol->Data.SectionNumber = Symbol->Section->Number; - Symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment) - + SymbolData->Offset; - } if (Symbol->should_keep()) { MakeSymbolReal(*Symbol, Header.NumberOfSymbols++); @@ -862,11 +886,15 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, const MCSectionCOFF &MCSec = static_cast(Section->MCData->getSection()); - COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection()); + const MCSymbol *COMDAT = MCSec.getCOMDATSymbol(); + assert(COMDAT); + COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(COMDAT); + assert(COMDATSymbol); + COFFSection *Assoc = COMDATSymbol->Section; if (!Assoc) - report_fatal_error(Twine("Missing associated COMDAT section ") + - MCSec.getAssocSection()->getSectionName() + - " for section " + MCSec.getSectionName()); + report_fatal_error( + Twine("Missing associated COMDAT section for section ") + + MCSec.getSectionName()); // Skip this section if the associated section is unused. if (Assoc->Number == -1)