1
0
Fork 0
This commit is contained in:
snow 2025-03-11 02:51:57 -04:00 committed by Pidgey
parent 024b25a912
commit 2c79b99644
No known key found for this signature in database
GPG Key ID: 1C7AB1C86292593A
4 changed files with 151 additions and 89 deletions

View File

@ -559,7 +559,7 @@ struct PrintVisitor : TypeManager::Visitor
}
else
{
if(member.bitSize != -1)
if(member.bitSize != type.sizeFUCK)
tname = StringUtils::sprintf("%s %s : %d", type.name.c_str(), member.name.c_str(), member.bitSize);
else
tname = StringUtils::sprintf("%s %s", type.name.c_str(), member.name.c_str());
@ -610,7 +610,7 @@ struct PrintVisitor : TypeManager::Visitor
if(!mParents.empty() && parent().type == Parent::Type::Union)
mOffset = parent().offset;
String tname = StringUtils::sprintf("%s %s %s", type.isunion ? "union" : "struct", member.assignedType.c_str(), member.name.c_str());
String tname = StringUtils::sprintf("%s %s %s", type.isUnion ? "union" : "struct", member.assignedType.c_str(), member.name.c_str());
TYPEDESCRIPTOR td;
td.expanded = true;
@ -625,7 +625,7 @@ struct PrintVisitor : TypeManager::Visitor
auto node = GuiTypeAddNode(mParents.empty() ? nullptr : parent().node, &td);
mPath.push_back((member.name == "display" ? type.name : member.assignedType) + ".");
mParents.push_back(Parent(type.isunion ? Parent::Union : Parent::Struct));
mParents.push_back(Parent(type.isUnion ? Parent::Union : Parent::Struct));
parent().node = node;
parent().size = td.size;
parent().offset = mOffset;

View File

@ -61,20 +61,22 @@ bool TypeManager::AddType(const std::string & owner, const std::string & type, c
return false;
}
bool TypeManager::AddStruct(const std::string & owner, const std::string & name)
bool TypeManager::AddStruct(const std::string & owner, const std::string & name, int constantSize)
{
StructUnion s;
s.name = name;
s.owner = owner;
s.sizeFUCK = constantSize;
return addStructUnion(s);
}
bool TypeManager::AddUnion(const std::string & owner, const std::string & name)
bool TypeManager::AddUnion(const std::string & owner, const std::string & name, int constantSize)
{
StructUnion u;
u.owner = owner;
u.name = name;
u.isunion = true;
u.isUnion = true;
u.sizeFUCK = constantSize;
return addStructUnion(u);
}
@ -83,7 +85,7 @@ bool TypeManager::AddEnum(const std::string & owner, const std::string & name, b
struct Enum e;
e.owner = owner;
e.name = name;
e.members = {};
e.members = { };
e.isFlags = isFlags;
e.sizeFUCK = size;
@ -104,7 +106,7 @@ bool TypeManager::AddEnumMember(const std::string & parent, const std::string &
return true;
}
bool TypeManager::AddMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize, int bitOffset, int bitSize)
bool TypeManager::AddStructMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize, int bitOffset, int bitSize)
{
if(!isDefined(type) && !validPtr(type))
return false;
@ -117,8 +119,16 @@ bool TypeManager::AddMember(const std::string & parent, const std::string & type
return false;
// cannot be pointer and bitfield
if(type.back() == '*' && bitSize != primitivesizes[Pointer] * 8)
return false;
if(type.back() == '*')
{
// this is a pointer type
auto expectedSize = primitivesizes[Pointer] * 8;
if(arrsize != 0)
expectedSize *= arrsize;
if(bitSize != expectedSize)
return false;
}
auto & s = found->second;
for(const auto & member : s.members)
@ -139,64 +149,28 @@ bool TypeManager::AddMember(const std::string & parent, const std::string & type
typeSize = Sizeof(type);
}
// cannot have a bitfield greater than typeSize
if(bitSize != -1 && bitSize > typeSize)
return false;
Member m;
m.name = name;
m.arrsize = arrsize;
m.type = type;
m.assignedType = type;
m.offsetFUCK = bitOffset;
m.bitSize = m.bitSize != typeSize ? bitSize : typeSize;
// maybe have a second size and fall back on bitsize if that one is -1
m.bitSize = bitSize;
if(bitOffset >= 0 && !s.isunion) //user-defined offset
if(bitOffset >= 0 && !s.isUnion) //user-defined offset
{
if(bitOffset < s.sizeFUCK)
return false;
if(bitOffset > s.sizeFUCK)
{
auto bitPadding = bitOffset - s.sizeFUCK;
if(bitPadding % 8 == 0)
{
ADD_BYTE_PADDING:
Member pad;
pad.type = "char";
pad.arrsize = bitPadding / 8;
// can just add byte padding
char padName[32] = { };
sprintf_s(padName, "padding%d", bitPadding / 8);
pad.name = padName;
s.members.push_back(pad);
}
else
{
auto remBit = bitPadding % 8;
Member pad;
pad.type = "long long";
pad.bitSize = remBit;
char padName[32] = { };
sprintf_s(padName, "padding%db", bitPadding);
pad.name = padName;
s.members.push_back(pad);
// more to add
if(bitPadding != remBit)
goto ADD_BYTE_PADDING;
}
s.sizeFUCK = bitOffset;
}
AppendStructPadding(parent, bitOffset);
}
s.members.push_back(m);
if(s.isunion)
if(s.isUnion)
{
if(typeSize > s.sizeFUCK)
s.sizeFUCK = typeSize;
@ -206,15 +180,63 @@ ADD_BYTE_PADDING:
s.sizeFUCK += typeSize;
}
s.members.push_back(m);
return true;
}
bool TypeManager::AppendMember(const std::string & type, const std::string & name, int arrsize, int offset)
bool TypeManager::AppendStructMember(const std::string & type, const std::string & name, int arrsize, int offset)
{
return AddMember(laststruct, type, name, arrsize, offset, -1);
return AddStructMember(laststruct, type, name, arrsize, offset, -1);
}
bool TypeManager::AddFunction(const std::string & owner, const std::string & name, const std::string & rettype, CallingConvention callconv,
bool TypeManager::AppendStructPadding(const std::string & parent, int targetOffset)
{
auto found = structs.find(parent);
if(found == structs.end())
return false;
auto & s = found->second;
if(s.sizeFUCK >= targetOffset || s.isUnion)
return false;
auto bitPadding = targetOffset - s.sizeFUCK;
if(bitPadding % 8 != 0)
{
const auto remBits = bitPadding % 8;
Member pad;
pad.type = "long long";
pad.bitSize = remBits;
char padName[32] = { };
sprintf_s(padName, "padding%db", remBits);
pad.name = padName;
s.members.push_back(pad);
// more to add
bitPadding -= remBits;
}
if(bitPadding)
{
Member pad;
pad.type = "char";
pad.arrsize = bitPadding / 8;
// can just add byte padding
char padName[32] = { };
sprintf_s(padName, "padding%d", bitPadding / 8);
pad.name = padName;
s.members.push_back(pad);
}
s.sizeFUCK = targetOffset;
return true;
}
bool TypeManager::AddFunction(const std::string & owner, const std::string & name, CallingConvention callconv,
bool noreturn)
{
auto found = functions.find(name);
@ -224,15 +246,28 @@ bool TypeManager::AddFunction(const std::string & owner, const std::string & nam
Function f;
f.owner = owner;
f.name = name;
if(rettype != "void" && !isDefined(rettype) && !validPtr(rettype))
return false;
f.rettype = rettype;
// return type cannot be set yet
f.callconv = callconv;
f.noreturn = noreturn;
functions.insert({ f.name, f });
return true;
}
bool TypeManager::AddFunctionReturn(const std::string & name, const std::string & rettype)
{
auto found = functions.find(name);
if(found == functions.end() || name.empty())
return false;
Function & f = found->second;
if(rettype != "void" && !isDefined(rettype) && !validPtr(rettype))
return false;
f.rettype = rettype;
return true;
}
bool TypeManager::AddArg(const std::string & function, const std::string & type, const std::string & name)
{
if(!isDefined(type) && !validPtr(type))
@ -258,7 +293,12 @@ int TypeManager::Sizeof(const std::string & type) const
{
auto foundT = types.find(type);
if(foundT != types.end())
{
if(!foundT->second.pointto.empty())
return Sizeof(foundT->second.pointto);
return foundT->second.sizeFUCK;
}
auto foundE = enums.find(type);
if(foundE != enums.end())
@ -332,7 +372,7 @@ bool TypeManager::RemoveType(const std::string & type)
static std::string getKind(const StructUnion & su)
{
return su.isunion ? "union" : "struct";
return su.isUnion ? "union" : "struct";
}
static std::string getKind(const Type & t)
@ -434,6 +474,9 @@ bool TypeManager::validPtr(const std::string & id)
auto foundE = enums.find(type);
if(foundE != enums.end())
owner = foundE->second.owner;
auto foundP = functions.find(type);
if(foundP != functions.end())
owner = foundP->second.owner;
return addType(owner, Pointer, id, type);
}
return false;
@ -554,19 +597,19 @@ bool AddUnion(const std::string & owner, const std::string & name)
bool AddMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize, int offset)
{
EXCLUSIVE_ACQUIRE(LockTypeManager);
return typeManager.AddMember(parent, type, name, arrsize, offset, -1);
return typeManager.AddStructMember(parent, type, name, arrsize, offset, -1);
}
bool AppendMember(const std::string & type, const std::string & name, int arrsize, int offset)
{
EXCLUSIVE_ACQUIRE(LockTypeManager);
return typeManager.AppendMember(type, name, arrsize, offset);
return typeManager.AppendStructMember(type, name, arrsize, offset);
}
bool AddFunction(const std::string & owner, const std::string & name, const std::string & rettype, Types::CallingConvention callconv, bool noreturn)
{
EXCLUSIVE_ACQUIRE(LockTypeManager);
return typeManager.AddFunction(owner, name, rettype, callconv, noreturn);
return typeManager.AddFunction(owner, name, callconv, noreturn);
}
bool AddArg(const std::string & function, const std::string & type, const std::string & name)
@ -651,9 +694,11 @@ static void loadStructUnions(const JSON suroot, std::vector<StructUnion> & struc
auto suname = json_string_value(json_object_get(vali, "name"));
if(!suname || !*suname)
continue;
curSu.name = suname;
curSu.members.clear();
curSu.isunion = json_boolean_value(json_object_get(vali, "isUnion"));
curSu.isUnion = json_boolean_value(json_object_get(vali, "isUnion"));
curSu.sizeFUCK = json_default_int(vali, "size", 0) * 8;
auto members = json_object_get(vali, "members");
@ -666,6 +711,7 @@ static void loadStructUnions(const JSON suroot, std::vector<StructUnion> & struc
auto name = json_string_value(json_object_get(valj, "name"));
if(!type || !*type || !name || !*name)
continue;
curMember.type = type;
curMember.name = name;
curMember.arrsize = json_default_int(valj, "arrsize", 0);
@ -787,15 +833,27 @@ void LoadModel(const std::string & owner, Model & model)
//Add all base struct/union types first to avoid errors later
for(auto & su : model.structUnions)
{
auto success = su.isunion ? typeManager.AddUnion(owner, su.name) : typeManager.AddStruct(owner, su.name);
auto success = su.isUnion ? typeManager.AddUnion(owner, su.name, 0) : typeManager.AddStruct(owner, su.name, 0);
if(!success)
{
//TODO properly handle errors
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add %s %s;\n"), su.isunion ? "union" : "struct", su.name.c_str());
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add %s %s;\n"), su.isUnion ? "union" : "struct", su.name.c_str());
su.name.clear(); //signal error
}
}
//Add base function types to avoid errors later
for(auto & function : model.functions)
{
auto success = typeManager.AddFunction(owner, function.name, function.callconv, function.noreturn);
if(!success)
{
//TODO properly handle errors
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add function %s %s()\n"), function.rettype.c_str(), function.name.c_str());
function.name.clear(); //signal error
}
}
for(auto & num : model.enums)
{
if(num.name.empty()) //skip error-signalled functions
@ -820,33 +878,28 @@ void LoadModel(const std::string & owner, Model & model)
}
}
//Add base function types to avoid errors later
for(auto & function : model.functions)
{
auto success = typeManager.AddFunction(owner, function.name, function.rettype, function.callconv, function.noreturn);
if(!success)
{
//TODO properly handle errors
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add function %s %s()\n"), function.rettype.c_str(), function.name.c_str());
function.name.clear(); //signal error
}
}
//Add struct/union members
for(auto & su : model.structUnions)
{
if(su.name.empty()) //skip error-signalled structs/unions
continue;
const auto suggested_size = su.sizeFUCK;
for(auto & member : su.members)
{
auto success = typeManager.AddMember(su.name, member.type, member.name, member.arrsize, member.offsetFUCK, member.bitSize);
if(su.name == "_SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION")
__debugbreak();
auto success = typeManager.AddStructMember(su.name, member.type, member.name, member.arrsize, member.offsetFUCK, member.bitSize);
if(!success)
{
//TODO properly handle errors
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add member %s %s.%s;\n"), member.type.c_str(), su.name.c_str(), member.name.c_str());
}
}
if(suggested_size != 0)
typeManager.AppendStructPadding(su.name, suggested_size);
}
for(auto & num : model.enums)
@ -870,6 +923,13 @@ void LoadModel(const std::string & owner, Model & model)
{
if(function.name.empty()) //skip error-signalled functions
continue;
bool status = typeManager.AddFunctionReturn(function.name, function.rettype);
if(!status)
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add return type %s.%s;\n"), function.name.c_str(), function.rettype.c_str());
}
for(auto & arg : function.args)
{
auto success = typeManager.AddArg(function.name, arg.type, arg.name);

View File

@ -51,8 +51,8 @@ namespace Types
std::string owner; //StructUnion owner
std::string name; //StructUnion identifier
std::vector<Member> members; //StructUnion members
bool isunion = false; //Is this a union?
int sizeFUCK = 0;
bool isUnion = false; //Is this a union?
int sizeFUCK = -1;
};
enum CallingConvention
@ -108,14 +108,16 @@ namespace Types
explicit TypeManager();
bool AddType(const std::string & owner, const std::string & type, const std::string & name);
bool AddStruct(const std::string & owner, const std::string & name);
bool AddUnion(const std::string & owner, const std::string & name);
bool AddStruct(const std::string & owner, const std::string & name, int constantSize = -1);
bool AddUnion(const std::string & owner, const std::string & name, int constantSize = -1);
bool AddEnum(const std::string & owner, const std::string & name, bool isFlags, uint8_t size);
bool AddEnumMember(const std::string & parent, const std::string & name, uint64_t value);
bool AddMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize, int bitOffset, int bitSize);
bool AppendMember(const std::string & type, const std::string & name, int arrsize = 0, int offset = -1);
bool AddFunction(const std::string & owner, const std::string & name, const std::string & rettype, CallingConvention callconv = Cdecl,
bool AddStructMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize, int bitOffset, int bitSize);
bool AppendStructMember(const std::string & type, const std::string & name, int arrsize = 0, int offset = -1);
bool AppendStructPadding(const std::string & type, int targetOffset);
bool AddFunction(const std::string & owner, const std::string & name, CallingConvention callconv = Cdecl,
bool noreturn = false);
bool AddFunctionReturn(const std::string & name, const std::string & rettype);
bool AddArg(const std::string & function, const std::string & type, const std::string & name);
bool AppendArg(const std::string & type, const std::string & name);
int Sizeof(const std::string & type) const;

View File

@ -190,7 +190,7 @@ bool ParseTypes(const std::string & parse, const std::string & owner)
if(isToken(Lexer::tok_struct) || isToken(Lexer::tok_union))
{
StructUnion su;
su.isunion = isToken(Lexer::tok_union);
su.isUnion = isToken(Lexer::tok_union);
index++;
if(isTokenList({ Lexer::tok_identifier, Lexer::tok_bropen }))
{
@ -201,7 +201,7 @@ bool ParseTypes(const std::string & parse, const std::string & owner)
if(isToken(Lexer::tok_eof))
{
errLine();
dprintf("unexpected eof in %s\n", su.isunion ? "union" : "struct");
dprintf("unexpected eof in %s\n", su.isUnion ? "union" : "struct");
return false;
}
if(isToken(Lexer::tok_bropen))