/// 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) { COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&SymbolData.getSymbol()); coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0; coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16; if (SymbolData.getFlags() & COFF::SF_WeakExternal) { coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; if (SymbolData.getSymbol().isVariable()) { coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; const MCExpr *Value = SymbolData.getSymbol().getVariableValue(); // FIXME: This assert message isn't very good. assert(Value->getKind() == MCExpr::SymbolRef && "Value must be a SymbolRef!"); const MCSymbolRefExpr *SymbolRef = static_cast<const MCSymbolRefExpr *>(Value); coff_symbol->Other = GetOrCreateCOFFSymbol(&SymbolRef->getSymbol()); } else { std::string WeakName = std::string(".weak.") + SymbolData.getSymbol().getName().str() + ".default"; COFFSymbol *WeakDefault = createSymbol(WeakName); WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL; WeakDefault->Data.Type = 0; WeakDefault->Data.Value = 0; coff_symbol->Other = WeakDefault; } // Setup the Weak External auxiliary symbol. coff_symbol->Aux.resize(1); memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); coff_symbol->Aux[0].AuxType = ATWeakExternal; coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; } // If no storage class was specified in the streamer, define it here. if (coff_symbol->Data.StorageClass == 0) { bool external = SymbolData.isExternal() || (SymbolData.Fragment == NULL); coff_symbol->Data.StorageClass = external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; } if (SymbolData.Fragment != NULL) coff_symbol->Section = SectionMap[&SymbolData.Fragment->getParent()->getSection()]; // Bind internal COFF symbol to MC symbol. coff_symbol->MCData = &SymbolData; SymbolMap[&SymbolData.getSymbol()] = coff_symbol; }
bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData, 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); // For now, all non-variable symbols are exported, // the linker will sort the rest out for us. return SymbolData.isExternal() || !SymbolData.getSymbol().isVariable(); }
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, MCAssembler &Assembler, const MCAsmLayout &Layout) { MCSymbol const &Symbol = SymbolData.getSymbol(); COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol); SymbolMap[&Symbol] = coff_symbol; if (SymbolData.getFlags() & COFF::SF_WeakExternal) { coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; if (Symbol.isVariable()) { const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue()); if (!SymRef) report_fatal_error("Weak externals may only alias symbols"); coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol()); } else { std::string WeakName = std::string(".weak.") + Symbol.getName().str() + ".default"; COFFSymbol *WeakDefault = createSymbol(WeakName); WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL; WeakDefault->Data.Type = 0; WeakDefault->Data.Value = 0; coff_symbol->Other = WeakDefault; } // Setup the Weak External auxiliary symbol. coff_symbol->Aux.resize(1); memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); coff_symbol->Aux[0].AuxType = ATWeakExternal; coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; 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(); } 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; coff_symbol->Data.StorageClass = external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; } if (Symbol.isAbsolute() || Symbol.AliasedSymbol().isVariable()) coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; else if (ResSymData.Fragment) coff_symbol->Section = SectionMap[&ResSymData.Fragment->getParent()->getSection()]; coff_symbol->MCData = &ResSymData; } }