error_or<symbol_sizes> getSymbolSizes(const COFFObjectFile& obj) { symbol_sizes sizes; for (symbol_iterator it : obj.symbols()) { auto sym = obj.getCOFFSymbol(*it); const coff_section *sec = nullptr; if (sym.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) continue; if (error_code ec = obj.getSection(sym.getSectionNumber(), sec)) return failure(ec.message()); if (!sec) continue; uint64_t size = (sec->VirtualAddress + sec->SizeOfRawData) - sym.getValue(); for (symbol_iterator it : obj.symbols()) { auto next = obj.getCOFFSymbol(*it); if (next.getSectionNumber() == sym.getSectionNumber()) { auto new_size = next.getValue() > sym.getValue() ? next.getValue() - sym.getValue() : size; size = new_size < size ? new_size : size; } } sizes.push_back(std::make_pair(*it, size)); } return success(std::move(sizes)); }
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 '?'; }
std::vector<symbol> read(const COFFObjectFile& obj) { std::vector<symbol> symbols; const pe32_header *pe32; if (error_code err = obj.getPE32Header(pe32)) llvm_binary_fail(err); for (auto it = obj.begin_symbols(); it != obj.end_symbols(); ++it) { auto sym = obj.getCOFFSymbol(it); if (!sym) llvm_binary_fail("not a coff symbol"); const coff_section *sec = nullptr; if (sym->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) continue; if (error_code ec = obj.getSection(sym->SectionNumber, sec)) llvm_binary_fail(ec); if (!sec) continue; uint64_t size = (sec->VirtualAddress + sec->SizeOfRawData) - sym->Value; for (auto it = obj.begin_symbols(); it != obj.end_symbols(); ++it) { auto next = obj.getCOFFSymbol(it); if (next->SectionNumber == sym->SectionNumber) { auto new_size = next->Value > sym->Value ? next->Value - sym->Value : size; size = new_size < size ? new_size : size; } } auto addr = sec->VirtualAddress + pe32->ImageBase + sym->Value; symbols.push_back(symbol(*it,addr,size)); } return symbols; }
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 '?'; }
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; }