std::error_code Decoder::dumpProcedureData(const COFFObjectFile &COFF) { for (const auto &Section : COFF.sections()) { StringRef SectionName; if (std::error_code EC = COFF.getSectionName(COFF.getCOFFSection(Section), SectionName)) return EC; if (SectionName.startswith(".pdata")) dumpProcedureData(COFF, Section); } return std::error_code(); }
static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { const coff_symbol *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 (Symb->SectionNumber > 0) { section_iterator SecI = Obj.section_end(); if (error(SymI->getSection(SecI))) return '?'; const coff_section *Section = Obj.getCOFFSection(SecI); Characteristics = Section->Characteristics; } switch (Symb->SectionNumber) { 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->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && Symb->Value == 0) return 's'; } return '?'; }
void Decoder::dumpProcedureData(const COFFObjectFile &COFF, const SectionRef Section) { ArrayRef<uint8_t> Contents; if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents)) return; if (Contents.size() % PDataEntrySize) { errs() << ".pdata content is not " << PDataEntrySize << "-byte aligned\n"; return; } for (unsigned EI = 0, EE = Contents.size() / PDataEntrySize; EI < EE; ++EI) if (!dumpProcedureDataEntry(COFF, Section, EI, Contents)) break; }
static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { COFFSymbolRef Symb = Obj.getCOFFSymbol(*I); // OK, this is COFF. symbol_iterator SymI(I); ErrorOr<StringRef> Name = SymI->getName(); if (error(Name.getError())) 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())) { ErrorOr<section_iterator> SecIOrErr = SymI->getSection(); if (error(SecIOrErr.getError())) return '?'; section_iterator SecI = *SecIOrErr; 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'; if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r'; if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) return 'b'; if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) return 'i'; // Check for section symbol. if (Symb.isSectionDefinition()) return 's'; } return '?'; }
std::vector<segment> read(const COFFObjectFile& obj) { std::vector<segment> segments; const pe32_header *pe32; if (error_code err = obj.getPE32Header(pe32)) llvm_binary_fail(err); for (auto it = obj.begin_sections(); it != obj.end_sections(); ++it) { const coff_section *s = obj.getCOFFSection(it); uint32_t c = static_cast<uint32_t>(s->Characteristics); if ( c & COFF::IMAGE_SCN_CNT_CODE || c & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA || c & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA ) segments.push_back(segment(*pe32, *s)); } return segments; }
bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF, const SectionRef &Section, uint64_t FunctionAddress, uint64_t VA) { ArrayRef<uint8_t> Contents; if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents)) return false; uint64_t SectionVA = Section.getAddress(); uint64_t Offset = VA - SectionVA; const ulittle32_t *Data = reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset); const ExceptionDataRecord XData(Data); DictScope XRS(SW, "ExceptionData"); SW.printNumber("FunctionLength", XData.FunctionLength() << 1); SW.printNumber("Version", XData.Vers()); SW.printBoolean("ExceptionData", XData.X()); SW.printBoolean("EpiloguePacked", XData.E()); SW.printBoolean("Fragment", XData.F()); SW.printNumber(XData.E() ? "EpilogueOffset" : "EpilogueScopes", XData.EpilogueCount()); SW.printNumber("ByteCodeLength", static_cast<uint64_t>(XData.CodeWords() * sizeof(uint32_t))); if (XData.E()) { ArrayRef<uint8_t> UC = XData.UnwindByteCode(); if (!XData.F()) { ListScope PS(SW, "Prologue"); decodeOpcodes(UC, 0, /*Prologue=*/true); } if (XData.EpilogueCount()) { ListScope ES(SW, "Epilogue"); decodeOpcodes(UC, XData.EpilogueCount(), /*Prologue=*/false); } } else { ArrayRef<ulittle32_t> EpilogueScopes = XData.EpilogueScopes(); ListScope ESS(SW, "EpilogueScopes"); for (const EpilogueScope ES : EpilogueScopes) { DictScope ESES(SW, "EpilogueScope"); SW.printNumber("StartOffset", ES.EpilogueStartOffset()); SW.printNumber("Condition", ES.Condition()); SW.printNumber("EpilogueStartIndex", ES.EpilogueStartIndex()); ListScope Opcodes(SW, "Opcodes"); decodeOpcodes(XData.UnwindByteCode(), ES.EpilogueStartIndex(), /*Prologue=*/false); } } if (XData.X()) { const uint32_t Address = XData.ExceptionHandlerRVA(); const uint32_t Parameter = XData.ExceptionHandlerParameter(); const size_t HandlerOffset = HeaderWords(XData) + (XData.E() ? 0 : XData.EpilogueCount()) + XData.CodeWords(); ErrorOr<SymbolRef> Symbol = getRelocatedSymbol(COFF, Section, HandlerOffset * sizeof(uint32_t)); if (!Symbol) Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true); StringRef Name; if (Symbol) Symbol->getName(Name); ListScope EHS(SW, "ExceptionHandler"); SW.printString("Routine", formatSymbol(Name, Address)); SW.printHex("Parameter", Parameter); } return true; }
static error_code getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I, char &Result) { const coff_symbol *symb = Obj.getCOFFSymbol(I); StringRef name; if (error_code ec = I->getName(name)) return ec; char ret = StringSwitch<char>(name) .StartsWith(".debug", 'N') .StartsWith(".sxdata", 'N') .Default('?'); if (ret != '?') { Result = ret; return object_error::success; } uint32_t Characteristics = 0; if (symb->SectionNumber > 0) { section_iterator SecI = Obj.end_sections(); if (error_code ec = I->getSection(SecI)) return ec; const coff_section *Section = Obj.getCOFFSection(SecI); Characteristics = Section->Characteristics; } switch (symb->SectionNumber) { case COFF::IMAGE_SYM_UNDEFINED: // Check storage classes. if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) { Result = 'w'; return object_error::success; // Don't do ::toupper. } else if (symb->Value != 0) // Check for common symbols. ret = 'c'; else ret = 'u'; break; case COFF::IMAGE_SYM_ABSOLUTE: ret = 'a'; break; case COFF::IMAGE_SYM_DEBUG: ret = 'n'; break; default: // Check section type. if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) ret = 't'; else if (Characteristics & COFF::IMAGE_SCN_MEM_READ && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. ret = 'r'; else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) ret = 'd'; else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ret = 'b'; else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) ret = 'i'; // Check for section symbol. else if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && symb->Value == 0) ret = 's'; } if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) ret = ::toupper(static_cast<unsigned char>(ret)); Result = ret; return object_error::success; }