35 : m_lib(lib), m_syms(syms) {}
38 std::string& entry_sym) {
41 ar::view<false>
lib(m_lib.data(), m_lib.size());
44 [&](std::pair<std::string_view, ar::entry_t&> itr) {
48 if (!itr.second.is_symbol_table() && !itr.second.is_string_table()) {
49 spdlog::info(
"extracted obj from archive: {}", itr.first);
50 std::vector<std::uint8_t> data(itr.second.begin(), itr.second.end());
51 m_objs.push_back(data);
56 m_objs.begin(), m_objs.end(), [&](std::vector<std::uint8_t>& img_data) {
57 auto img = reinterpret_cast<coff::image_t*>(img_data.data());
58 for (auto idx = 0u; idx < img->file_header.num_symbols; ++idx) {
59 auto sym = img->get_symbol(idx);
60 if (sym->section_index - 1 > img->file_header.num_sections)
63 auto sym_name = symbol_t::name(img, sym);
64 if (sym_name.length()) {
65 auto sym_hash = symbol_t::hash(sym_name.data());
68 ? next_sym(img, img->get_section(sym->section_index - 1),
72 m_lookup_tbl[sym_hash].emplace_back(img, sym, sym_size);
79 spdlog::info(
"extracted {} symbols being used...",
80 ext_used_syms(entry_sym.data()));
85 std::for_each(m_used_syms.begin(), m_used_syms.end(), [&](
sym_data_t data) {
86 auto [img, sym, size] = data;
92 if (m_processed_objs.emplace(img).second) {
93 for (auto idx = 0u; idx < img->file_header.num_sections; ++idx) {
94 auto scn = img->get_section(idx);
96 std::string(scn->name.to_string(img->get_strings()))
98 .append(std::to_string(idx))
100 .append(std::to_string(img->file_header.timedate_stamp));
105 m_scn_hash_tbl.insert({scn, decomp::symbol_t::hash(scn_sym_name)});
112 if (sym->has_section()) {
113 if (sym->derived_type == coff::derived_type_id::function) {
114 auto scn = img->get_section(sym->section_index - 1);
116 scn->name.to_string(img->get_strings()) == INSTR_SPLIT_SECTION_NAME
117 ? decomp::sym_type_t::instruction
118 : decomp::sym_type_t::function;
120 auto fn_size = next_sym(img, scn, sym);
121 auto fn_bgn = scn->ptr_raw_data + reinterpret_cast<std::uint8_t*>(img) +
124 std::vector<std::uint8_t> fn(fn_bgn, fn_bgn + fn_size);
125 decomp::routine_t rtn(sym, img, scn, fn, dcmp_type);
127 auto syms = rtn.decompose();
128 m_syms->put_symbols(syms);
129 }
else if (sym->storage_class == coff::storage_class_id::public_symbol ||
130 sym->storage_class == coff::storage_class_id::private_symbol) {
131 auto scn = img->get_section(sym->section_index - 1);
132 auto scn_sym = m_syms->sym_from_hash(m_scn_hash_tbl[scn]);
137 if (!scn_sym.has_value()) {
139 std::string(scn->name.to_string(img->get_strings()))
141 .append(std::to_string(sym->section_index - 1))
143 .append(std::to_string(img->file_header.timedate_stamp));
145 std::vector<std::uint8_t> scn_data(scn->size_raw_data);
146 if (scn->characteristics.cnt_uninit_data) {
147 scn_data.insert(scn_data.begin(), scn->size_raw_data, 0);
151 reinterpret_cast<std::uint8_t*>(img) + scn->ptr_raw_data,
152 reinterpret_cast<std::uint8_t*>(img) + scn->ptr_raw_data +
156 std::vector<recomp::reloc_t> relocs;
157 auto scn_relocs = reinterpret_cast<coff::reloc_t*>(
158 scn->ptr_relocs + reinterpret_cast<std::uint8_t*>(img));
160 for (auto idx = 0u; idx < scn->num_relocs; ++idx) {
161 auto scn_reloc = &scn_relocs[idx];
162 auto sym_reloc = img->get_symbol(scn_relocs[idx].symbol_index);
163 auto sym_name = symbol_t::name(img, sym_reloc);
164 auto sym_hash = decomp::symbol_t::hash(sym_name.data());
166 recomp::reloc_t(scn_reloc->virtual_address - sym->value,
167 sym_hash, sym_name.data()));
170 decomp::symbol_t new_scn_sym(img, scn_sym_name, 0, scn_data, scn, {},
171 relocs, sym_type_t::section);
173 m_syms->put_symbol(new_scn_sym);
179 sym->value, {}, scn, sym, {},
182 m_syms->put_symbol(new_sym);
184 }
else if (sym->storage_class ==
185 coff::storage_class_id::
186 external_definition) {
191 std::vector<std::uint8_t> data(sym->value, 0);
192 decomp::symbol_t bss_sym(img, symbol_t::name(img, sym).data(), {},
data,
195 m_syms->put_symbol(bss_sym);
204 std::uint32_t decomp_t::next_sym(coff::image_t* img,
205 coff::section_header_t* hdr,
210 std::uint32_t res = hdr->size_raw_data;
211 for (
auto idx = 0u; idx < img->file_header.num_symbols; ++idx) {
212 auto q = img->get_symbol(idx);
214 q->section_index == s->section_index && q != s)
215 if (q->value > s->value && q->value < res)
221 std::uint32_t decomp_t::ext_used_syms(
const std::string&& entry_sym) {
222 std::optional<sym_data_t> entry = get_symbol(entry_sym.data());
223 if (!entry.has_value())
226 std::set<coff::symbol_t*> cache;
227 const auto finding_syms = [&]() ->
bool {
228 for (
auto itr = m_used_syms.begin(); itr != m_used_syms.end(); ++itr) {
229 auto [img, sym, size] = *itr;
230 if (sym->has_section() && !cache.count(sym) && size) {
231 auto scn = img->get_section(sym->section_index - 1);
232 auto num_relocs = scn->num_relocs;
233 auto relocs =
reinterpret_cast<coff::reloc_t*
>(
234 scn->ptr_relocs +
reinterpret_cast<std::uint8_t*
>(img));
236 for (
auto idx = 0u; idx < num_relocs; ++idx) {
237 auto reloc = &relocs[idx];
239 if (reloc->virtual_address >= sym->value &&
240 reloc->virtual_address < sym->value + size) {
241 auto reloc_sym = img->get_symbol(reloc->symbol_index);
242 auto sym_name = symbol_t::name(img, reloc_sym);
243 entry = get_symbol(sym_name);
244 if (m_used_syms.emplace(entry.value()).second)
254 m_used_syms.emplace(entry.value());
255 for (m_used_syms.emplace(entry.value()); finding_syms();)
258 return m_used_syms.size();
261 std::optional<sym_data_t> decomp_t::get_symbol(
const std::string_view& name) {
262 coff::image_t* img = {};
263 coff::symbol_t* sym = {};
264 std::uint32_t size = {};
266 auto& syms = m_lookup_tbl[symbol_t::hash(name.data())];
267 for (
auto idx = 0u; idx < syms.size(); ++idx) {
268 img = std::get<0>(syms[idx]);
269 sym = std::get<1>(syms[idx]);
270 size = std::get<2>(syms[idx]);
271 if (sym->has_section())
272 return {{img, sym, size}};
276 return {{img, sym, size}};
281 std::vector<routine_t> decomp_t::rtns() {
285 std::vector<std::uint8_t> decomp_t::lib() {
289 std::vector<std::vector<std::uint8_t>> decomp_t::objs() {
297 std::map<coff::section_header_t*, std::size_t>& decomp_t::scn_hash_tbl() {
298 return m_scn_hash_tbl;
decomp_t(std::vector< std::uint8_t > &lib, recomp::symbol_table_t *syms)
the explicit constructor for decomp_t
std::vector< std::uint8_t > lib()
gets a vector of bytes consisting of the lib file.
std::optional< recomp::symbol_table_t * > decompose(std::string &entry_sym)
decomposes (extracts) the symbols used. this function determines all used symbols given the entry poi...
symbol_t is an abstraction upon the coff symbol. this allows for easier manipulation of the symbol....
this class is a high level wrapper for a hashmap that contains decomp::symbol_t values....
the namespace that contains all of the decomposition related code.
std::tuple< coff::image_t *, coff::symbol_t *, std::uint32_t > sym_data_t
meta symbol data. consists of the coff image which contains the coff symbol, the coff symbol itself,...