|
|
|
@ -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();)
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|