ErrorOr<section_iterator> COFFObjectFile::getSymbolSection(DataRefImpl Ref) const { COFFSymbolRef Symb = getCOFFSymbol(Ref); if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) return section_end(); const coff_section *Sec = nullptr; if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) return EC; DataRefImpl Ret; Ret.p = reinterpret_cast<uintptr_t>(Sec); return section_iterator(SectionRef(Ret, this)); }
static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { COFFSymbolRef Symb = Obj.getCOFFSymbol(*I); // OK, this is COFF. symbol_iterator SymI(I); StringRef Name; if (error(SymI->getName(Name))) return '?'; char Ret = StringSwitch<char>(Name) .StartsWith(".debug", 'N') .StartsWith(".sxdata", 'N') .Default('?'); if (Ret != '?') return Ret; uint32_t Characteristics = 0; if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { section_iterator SecI = Obj.section_end(); if (error(SymI->getSection(SecI))) return '?'; const coff_section *Section = Obj.getCOFFSection(*SecI); Characteristics = Section->Characteristics; } switch (Symb.getSectionNumber()) { case COFF::IMAGE_SYM_DEBUG: return 'n'; default: // Check section type. if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) return 't'; else if (Characteristics & COFF::IMAGE_SCN_MEM_READ && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. return 'r'; else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) return 'd'; else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) return 'b'; else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) return 'i'; // Check for section symbol. else if (Symb.isSectionDefinition()) return 's'; } return '?'; }
uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { COFFSymbolRef Symb = getCOFFSymbol(Ref); uint32_t Result = SymbolRef::SF_None; if (Symb.isExternal() || Symb.isWeakExternal()) Result |= SymbolRef::SF_Global; if (Symb.isWeakExternal()) Result |= SymbolRef::SF_Weak; if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE) Result |= SymbolRef::SF_Absolute; if (Symb.isFileRecord()) Result |= SymbolRef::SF_FormatSpecific; if (Symb.isSectionDefinition()) Result |= SymbolRef::SF_FormatSpecific; if (Symb.isCommon()) Result |= SymbolRef::SF_Common; if (Symb.isAnyUndefined()) Result |= SymbolRef::SF_Undefined; return Result; }
void ObjectFile::initializeSymbols() { uint32_t NumSymbols = COFFObj->getNumberOfSymbols(); SymbolBodies.reserve(NumSymbols); SparseSymbolBodies.resize(NumSymbols); llvm::SmallVector<std::pair<Undefined *, uint32_t>, 8> WeakAliases; int32_t LastSectionNumber = 0; for (uint32_t I = 0; I < NumSymbols; ++I) { // Get a COFFSymbolRef object. auto SymOrErr = COFFObj->getSymbol(I); error(SymOrErr, Twine("broken object file: ") + getName()); COFFSymbolRef Sym = *SymOrErr; const void *AuxP = nullptr; if (Sym.getNumberOfAuxSymbols()) AuxP = COFFObj->getSymbol(I + 1)->getRawPtr(); bool IsFirst = (LastSectionNumber != Sym.getSectionNumber()); SymbolBody *Body = nullptr; if (Sym.isUndefined()) { Body = createUndefined(Sym); } else if (Sym.isWeakExternal()) { Body = createUndefined(Sym); uint32_t TagIndex = static_cast<const coff_aux_weak_external *>(AuxP)->TagIndex; WeakAliases.emplace_back((Undefined *)Body, TagIndex); } else { Body = createDefined(Sym, AuxP, IsFirst); } if (Body) { SymbolBodies.push_back(Body); SparseSymbolBodies[I] = Body; } I += Sym.getNumberOfAuxSymbols(); LastSectionNumber = Sym.getSectionNumber(); } for (auto WeakAlias : WeakAliases) WeakAlias.first->WeakAlias = SparseSymbolBodies[WeakAlias.second]; }
void ObjectFile::initializeSymbols() { uint32_t NumSymbols = COFFObj->getNumberOfSymbols(); SymbolBodies.reserve(NumSymbols); SparseSymbolBodies.resize(NumSymbols); llvm::SmallVector<Undefined *, 8> WeakAliases; int32_t LastSectionNumber = 0; for (uint32_t I = 0; I < NumSymbols; ++I) { // Get a COFFSymbolRef object. auto SymOrErr = COFFObj->getSymbol(I); error(SymOrErr, Twine("broken object file: ") + getName()); COFFSymbolRef Sym = *SymOrErr; const void *AuxP = nullptr; if (Sym.getNumberOfAuxSymbols()) AuxP = COFFObj->getSymbol(I + 1)->getRawPtr(); bool IsFirst = (LastSectionNumber != Sym.getSectionNumber()); SymbolBody *Body = nullptr; if (Sym.isUndefined()) { Body = createUndefined(Sym); } else if (Sym.isWeakExternal()) { Body = createWeakExternal(Sym, AuxP); WeakAliases.push_back((Undefined *)Body); } else { Body = createDefined(Sym, AuxP, IsFirst); } if (Body) { SymbolBodies.push_back(Body); SparseSymbolBodies[I] = Body; } I += Sym.getNumberOfAuxSymbols(); LastSectionNumber = Sym.getSectionNumber(); } for (Undefined *U : WeakAliases) U->WeakAlias = SparseSymbolBodies[(uintptr_t)U->WeakAlias]; }
ErrorOr<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const { uint64_t Result = getSymbolValue(Ref); COFFSymbolRef Symb = getCOFFSymbol(Ref); int32_t SectionNumber = Symb.getSectionNumber(); if (Symb.isAnyUndefined() || Symb.isCommon() || COFF::isReservedSectionNumber(SectionNumber)) return Result; const coff_section *Section = nullptr; if (std::error_code EC = getSection(SectionNumber, Section)) return EC; Result += Section->VirtualAddress; // The section VirtualAddress does not include ImageBase, and we want to // return virtual addresses. Result += getImageBase(); return Result; }
ErrorOr<SymbolRef::Type> COFFObjectFile::getSymbolType(DataRefImpl Ref) const { COFFSymbolRef Symb = getCOFFSymbol(Ref); int32_t SectionNumber = Symb.getSectionNumber(); if (Symb.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) return SymbolRef::ST_Function; if (Symb.isAnyUndefined()) return SymbolRef::ST_Unknown; if (Symb.isCommon()) return SymbolRef::ST_Data; if (Symb.isFileRecord()) return SymbolRef::ST_File; // TODO: perhaps we need a new symbol type ST_Section. if (SectionNumber == COFF::IMAGE_SYM_DEBUG || Symb.isSectionDefinition()) return SymbolRef::ST_Debug; if (!COFF::isReservedSectionNumber(SectionNumber)) return SymbolRef::ST_Data; return SymbolRef::ST_Other; }
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"; } } }
unsigned COFFObjectFile::getSymbolSectionID(SymbolRef Sym) const { COFFSymbolRef Symb = getCOFFSymbol(Sym.getRawDataRefImpl()); return Symb.getSectionNumber(); }