Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { // Relative symbols are unrepresentable in a COFF symbol table. if (isa<DefinedSynthetic>(Def)) return None; if (auto *D = dyn_cast<DefinedRegular>(Def)) { // Don't write dead symbols or symbols in codeview sections to the symbol // table. if (!D->getChunk()->isLive() || D->getChunk()->isCodeView()) return None; } if (auto *Sym = dyn_cast<DefinedImportData>(Def)) if (!Sym->File->Live) return None; if (auto *Sym = dyn_cast<DefinedImportThunk>(Def)) if (!Sym->WrappedSym->File->Live) return None; coff_symbol16 Sym; StringRef Name = Def->getName(); if (Name.size() > COFF::NameSize) { Sym.Name.Offset.Zeroes = 0; Sym.Name.Offset.Offset = addEntryToStringTable(Name); } else { memset(Sym.Name.ShortName, 0, COFF::NameSize); memcpy(Sym.Name.ShortName, Name.data(), Name.size()); } if (auto *D = dyn_cast<DefinedCOFF>(Def)) { COFFSymbolRef Ref = D->getCOFFSymbol(); Sym.Type = Ref.getType(); Sym.StorageClass = Ref.getStorageClass(); } else { Sym.Type = IMAGE_SYM_TYPE_NULL; Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; } Sym.NumberOfAuxSymbols = 0; switch (Def->kind()) { case SymbolBody::DefinedAbsoluteKind: Sym.Value = Def->getRVA(); Sym.SectionNumber = IMAGE_SYM_ABSOLUTE; break; default: { uint64_t RVA = Def->getRVA(); OutputSection *Sec = nullptr; for (OutputSection *S : OutputSections) { if (S->getRVA() > RVA) break; Sec = S; } Sym.Value = RVA - Sec->getRVA(); Sym.SectionNumber = Sec->SectionIndex; break; } } return Sym; }
Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { if (auto *D = dyn_cast<DefinedRegular>(Def)) if (!D->getChunk()->isLive()) return None; coff_symbol16 Sym; StringRef Name = Def->getName(); if (Name.size() > COFF::NameSize) { Sym.Name.Offset.Zeroes = 0; Sym.Name.Offset.Offset = addEntryToStringTable(Name); } else { memset(Sym.Name.ShortName, 0, COFF::NameSize); memcpy(Sym.Name.ShortName, Name.data(), Name.size()); } if (auto *D = dyn_cast<DefinedCOFF>(Def)) { COFFSymbolRef Ref = D->getCOFFSymbol(); Sym.Type = Ref.getType(); Sym.StorageClass = Ref.getStorageClass(); } else { Sym.Type = IMAGE_SYM_TYPE_NULL; Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; } Sym.NumberOfAuxSymbols = 0; switch (Def->kind()) { case SymbolBody::DefinedAbsoluteKind: case SymbolBody::DefinedRelativeKind: Sym.Value = Def->getRVA(); Sym.SectionNumber = IMAGE_SYM_ABSOLUTE; break; default: { uint64_t RVA = Def->getRVA(); OutputSection *Sec = nullptr; for (OutputSection *S : OutputSections) { if (S->getRVA() > RVA) break; Sec = S; } Sym.Value = RVA - Sec->getRVA(); Sym.SectionNumber = Sec->SectionIndex; break; } } return Sym; }
void COFFDumper::printSymbol(const SymbolRef &Sym) { DictScope D(W, "Symbol"); COFFSymbolRef Symbol = Obj->getCOFFSymbol(Sym); const coff_section *Section; if (std::error_code EC = Obj->getSection(Symbol.getSectionNumber(), Section)) { W.startLine() << "Invalid section number: " << EC.message() << "\n"; W.flush(); return; } StringRef SymbolName; if (Obj->getSymbolName(Symbol, SymbolName)) SymbolName = ""; StringRef SectionName = ""; ErrorOr<StringRef> Res = getSectionName(Obj, Symbol.getSectionNumber(), Section); if (Res) SectionName = *Res; W.printString("Name", SymbolName); W.printNumber("Value", Symbol.getValue()); W.printNumber("Section", SectionName, Symbol.getSectionNumber()); W.printEnum ("BaseType", Symbol.getBaseType(), makeArrayRef(ImageSymType)); W.printEnum ("ComplexType", Symbol.getComplexType(), makeArrayRef(ImageSymDType)); W.printEnum ("StorageClass", Symbol.getStorageClass(), makeArrayRef(ImageSymClass)); W.printNumber("AuxSymbolCount", Symbol.getNumberOfAuxSymbols()); for (uint8_t I = 0; I < Symbol.getNumberOfAuxSymbols(); ++I) { if (Symbol.isFunctionDefinition()) { const coff_aux_function_definition *Aux; error(getSymbolAuxData(Obj, Symbol, I, Aux)); DictScope AS(W, "AuxFunctionDef"); W.printNumber("TagIndex", Aux->TagIndex); W.printNumber("TotalSize", Aux->TotalSize); W.printHex("PointerToLineNumber", Aux->PointerToLinenumber); W.printHex("PointerToNextFunction", Aux->PointerToNextFunction); } else if (Symbol.isAnyUndefined()) { const coff_aux_weak_external *Aux; error(getSymbolAuxData(Obj, Symbol, I, Aux)); ErrorOr<COFFSymbolRef> Linked = Obj->getSymbol(Aux->TagIndex); StringRef LinkedName; std::error_code EC = Linked.getError(); if (EC || (EC = Obj->getSymbolName(*Linked, LinkedName))) { LinkedName = ""; error(EC); } DictScope AS(W, "AuxWeakExternal"); W.printNumber("Linked", LinkedName, Aux->TagIndex); W.printEnum ("Search", Aux->Characteristics, makeArrayRef(WeakExternalCharacteristics)); } else if (Symbol.isFileRecord()) { const char *FileName; error(getSymbolAuxData(Obj, Symbol, I, FileName)); DictScope AS(W, "AuxFileRecord"); StringRef Name(FileName, Symbol.getNumberOfAuxSymbols() * Obj->getSymbolTableEntrySize()); W.printString("FileName", Name.rtrim(StringRef("\0", 1))); break; } else if (Symbol.isSectionDefinition()) { const coff_aux_section_definition *Aux; error(getSymbolAuxData(Obj, Symbol, I, Aux)); int32_t AuxNumber = Aux->getNumber(Symbol.isBigObj()); DictScope AS(W, "AuxSectionDef"); W.printNumber("Length", Aux->Length); W.printNumber("RelocationCount", Aux->NumberOfRelocations); W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers); W.printHex("Checksum", Aux->CheckSum); W.printNumber("Number", AuxNumber); W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect)); if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { const coff_section *Assoc; StringRef AssocName = ""; std::error_code EC = Obj->getSection(AuxNumber, Assoc); ErrorOr<StringRef> Res = getSectionName(Obj, AuxNumber, Assoc); if (Res) AssocName = *Res; if (!EC) EC = Res.getError(); if (EC) { AssocName = ""; error(EC); } W.printNumber("AssocSection", AssocName, AuxNumber); } } else if (Symbol.isCLRToken()) { const coff_aux_clr_token *Aux; error(getSymbolAuxData(Obj, Symbol, I, Aux)); ErrorOr<COFFSymbolRef> ReferredSym = Obj->getSymbol(Aux->SymbolTableIndex); StringRef ReferredName; std::error_code EC = ReferredSym.getError(); if (EC || (EC = Obj->getSymbolName(*ReferredSym, ReferredName))) { ReferredName = ""; error(EC); } DictScope AS(W, "AuxCLRToken"); W.printNumber("AuxType", Aux->AuxType); W.printNumber("Reserved", Aux->Reserved); W.printNumber("SymbolTableIndex", ReferredName, Aux->SymbolTableIndex); } else { W.startLine() << "<unhandled auxiliary record>\n"; } } }