Support pre-initializing vtable pointers from symbols.xml

develop
Alexander Gavrilov 2012-04-12 10:54:53 +04:00
parent d874c3b538
commit 583ccdcc0c
4 changed files with 40 additions and 28 deletions

@ -128,17 +128,6 @@ void compound_identity::Init(Core *core)
// they are called in an undefined order.
for (compound_identity *p = list; p; p = p->next)
p->doInit(core);
//FIXME: ... nuked. the group was empty...
/*
// Read pre-filled vtable ptrs
OffsetGroup *ptr_table = core->vinfo->getGroup("vtable");
for (virtual_identity *p = list; p; p = p->next) {
void * tmp;
if (ptr_table->getSafeAddress(p->getName(),tmp))
p->vtable_ptr = tmp;
}
*/
}
bitfield_identity::bitfield_identity(size_t size,
@ -223,17 +212,23 @@ virtual_identity::virtual_identity(size_t size, TAllocateFn alloc,
{
}
/* Vtable name to identity lookup. */
static std::map<std::string, virtual_identity*> name_lookup;
/* Vtable pointer to identity lookup. */
std::map<void*, virtual_identity*> virtual_identity::known;
void virtual_identity::doInit(Core *core)
{
struct_identity::doInit(core);
name_lookup[getOriginalName()] = this;
}
auto vtname = getOriginalName();
name_lookup[vtname] = this;
/* Vtable to identity lookup. */
std::map<void*, virtual_identity*> virtual_identity::known;
vtable_ptr = core->vinfo->getVTable(vtname);
if (vtable_ptr)
known[vtable_ptr] = this;
}
virtual_identity *virtual_identity::get(virtual_ptr instance_ptr)
{
@ -265,8 +260,8 @@ virtual_identity *virtual_identity::get(virtual_ptr instance_ptr)
<< ", previous 0x" << unsigned(p->vtable_ptr) << std::dec << std::endl;
abort();
} else if (!p->vtable_ptr) {
std::cerr << "class '" << p->getName() << "': vtable = 0x"
<< std::hex << unsigned(vtable) << std::dec << std::endl;
std::cerr << "<vtable-address name='" << p->getOriginalName() << "' value='0x"
<< std::hex << unsigned(vtable) << std::dec << "'/>" << std::endl;
}
known[vtable] = p;

@ -118,7 +118,8 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
string type, name, value;
const char *cstr_type = pMemEntry->Value();
type = cstr_type;
if(type == "global-address")
bool is_vtable = (type == "vtable-address");
if(is_vtable || type == "global-address")
{
const char *cstr_key = pMemEntry->Attribute("name");
if(!cstr_key)
@ -129,7 +130,11 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
cerr << "Dummy symbol table entry: " << cstr_key << endl;
continue;
}
mem->setAddress(cstr_key, strtol(cstr_value, 0, 0));
uint32_t addr = strtol(cstr_value, 0, 0);
if (is_vtable)
mem->setVTable(cstr_key, addr);
else
mem->setAddress(cstr_key, addr);
}
else if (type == "md5-hash")
{

@ -51,6 +51,7 @@ namespace DFHack
std::vector <std::string> md5_list;
std::vector <uint32_t> PE_list;
std::map <std::string, uint32_t> Addresses;
std::map <std::string, uint32_t> VTables;
uint32_t base;
std::string version;
OSType OS;
@ -66,6 +67,7 @@ namespace DFHack
md5_list = rhs.md5_list;
PE_list = rhs.PE_list;
Addresses = rhs.Addresses;
VTables = rhs.VTables;
base = rhs.base;
version = rhs.version;
OS = rhs.OS;
@ -79,13 +81,10 @@ namespace DFHack
int64_t newx = new_base;
int64_t rebase = newx - old;
base = new_base;
auto iter = Addresses.begin();
while (iter != Addresses.end())
{
uint32_t & ref = (*iter).second;
ref += rebase;
iter ++;
}
for (auto iter = Addresses.begin(); iter != Addresses.end(); ++iter)
iter->second += rebase;
for (auto iter = VTables.begin(); iter != VTables.end(); ++iter)
iter->second += rebase;
};
void addMD5 (const std::string & _md5)
@ -125,6 +124,7 @@ namespace DFHack
value = (T) (*i).second;
return true;
};
uint32_t getAddress (const std::string& key) const
{
auto i = Addresses.find(key);
@ -133,6 +133,18 @@ namespace DFHack
return (*i).second;
}
void setVTable (const std::string& key, const uint32_t value)
{
VTables[key] = value;
};
void *getVTable (const std::string& key) const
{
auto i = VTables.find(key);
if(i == VTables.end())
return 0;
return (void*)i->second;
}
void setOS(const OSType os)
{
OS = os;

@ -454,6 +454,8 @@ bool Items::setOwner(df::item *item, df::unit *unit)
vector_erase_at(item->itemrefs, i);
}
item->flags.bits.owned = false;
if (unit)
{
auto ref = df::allocate<df::general_ref_unit_itemownerst>();
@ -466,8 +468,6 @@ bool Items::setOwner(df::item *item, df::unit *unit)
insert_into_vector(unit->owned_items, item->id);
item->itemrefs.push_back(ref);
}
else
item->flags.bits.owned = false;
return true;
}