|
|
|
@ -219,39 +219,62 @@ std::uint32_t decomp_t::next_sym(coff::image_t* img,
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::uint32_t decomp_t::ext_used_syms(const std::string&& entry_sym) { |
|
|
|
|
// start with the entry point symbol...
|
|
|
|
|
std::optional<sym_data_t> entry = get_symbol(entry_sym.data()); |
|
|
|
|
|
|
|
|
|
// if the entry point symbol cant be found simply return 0 (for 0 symbols
|
|
|
|
|
// extracted)...
|
|
|
|
|
if (!entry.has_value()) |
|
|
|
|
return 0u; |
|
|
|
|
|
|
|
|
|
// little memoization for perf boost... :^)
|
|
|
|
|
std::set<coff::symbol_t*> cache; |
|
|
|
|
const auto finding_syms = [&]() -> bool { |
|
|
|
|
// for all the symbols...
|
|
|
|
|
for (auto itr = m_used_syms.begin(); itr != m_used_syms.end(); ++itr) { |
|
|
|
|
auto [img, sym, size] = *itr; |
|
|
|
|
// if the symbol has a section and its not already in the cache...
|
|
|
|
|
if (sym->has_section() && !cache.count(sym) && size) { |
|
|
|
|
auto scn = img->get_section(sym->section_index - 1); |
|
|
|
|
auto num_relocs = scn->num_relocs; |
|
|
|
|
auto relocs = reinterpret_cast<coff::reloc_t*>( |
|
|
|
|
scn->ptr_relocs + reinterpret_cast<std::uint8_t*>(img)); |
|
|
|
|
|
|
|
|
|
// see if there are any relocations inside of the symbol...
|
|
|
|
|
for (auto idx = 0u; idx < num_relocs; ++idx) { |
|
|
|
|
auto reloc = &relocs[idx]; |
|
|
|
|
// if the reloc is inside of the current symbol...
|
|
|
|
|
if (reloc->virtual_address >= sym->value && |
|
|
|
|
reloc->virtual_address < sym->value + size) { |
|
|
|
|
// get the symbol for the relocation and add it to the m_used_symbol
|
|
|
|
|
// vector...
|
|
|
|
|
auto reloc_sym = img->get_symbol(reloc->symbol_index); |
|
|
|
|
auto sym_name = symbol_t::name(img, reloc_sym); |
|
|
|
|
entry = get_symbol(sym_name); |
|
|
|
|
// if the symbol already exists in the m_used_syms vector then we
|
|
|
|
|
// return out of this function and continue looping over all symbols
|
|
|
|
|
// recursively...
|
|
|
|
|
if (m_used_syms.emplace(entry.value()).second) |
|
|
|
|
return true; |
|
|
|
|
return true; // returns to the for loop below this lambda. the
|
|
|
|
|
// return true here means we added yet another
|
|
|
|
|
// symbol to the "m_used_syms" vector...
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// cache the symbol so we dont need to process it again...
|
|
|
|
|
cache.emplace(sym); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
return false; // only ever returns false here when every single symbol
|
|
|
|
|
// inside of m_used_syms has been looked at to see if all of
|
|
|
|
|
// its relocation symbols are included in the m_used_syms
|
|
|
|
|
// vector (meaning we got all the used symbols...)
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// add the entry point symbol...
|
|
|
|
|
m_used_syms.emplace(entry.value()); |
|
|
|
|
|
|
|
|
|
// keep recursively adding symbols until we found them all..
|
|
|
|
|
for (m_used_syms.emplace(entry.value()); finding_syms();) |
|
|
|
|
; |
|
|
|
|
|
|
|
|
|