diff --git a/src/dbg/commands/cmd-types.cpp b/src/dbg/commands/cmd-types.cpp index b6b7aac9..061034ab 100644 --- a/src/dbg/commands/cmd-types.cpp +++ b/src/dbg/commands/cmd-types.cpp @@ -348,24 +348,29 @@ struct PrintVisitor : TypeManager::Visitor } String valueStr; - size_t byteSize = (type->offset % 8 + type->size + 7) / 8; - Memory data(byteSize); - + Memory data((type->size + 7) / 8); if(MemRead(type->addr + (type->offset / 8), data(), data.size())) { if(type->reverse) std::reverse(data(), data() + data.size()); - size_t bitOffset = type->offset % 8; - if(bitOffset != 0) + size_t bitsFromRead = type->offset % 8; + if(bitsFromRead != 0) // have to shift the data over { - uint64_t extractedValue = 0; - memcpy(&extractedValue, data(), std::min(sizeof(extractedValue), data.size())); - extractedValue >>= bitOffset; - extractedValue &= (1ULL << type->size) - 1; + uint8_t currentCarry = 0; + for(size_t i = data.size(); i > 0; i--) + { + uint8_t newCarry = data()[i - 1] << (8 - bitsFromRead); + data()[i - 1] = (data()[i - 1] >> bitsFromRead) | currentCarry; + currentCarry = newCarry; + } + } - memset(data(), 0, data.size()); - memcpy(data(), &extractedValue, std::min(sizeof(extractedValue), data.size())); + size_t bitsOverread = data.size() * 8 - type->size; + if(bitsOverread) + { + // Clear the overread bits + data()[data.size() - 1] &= (1 << (type->size % 8)) - 1; } switch(Primitive(type->id)) @@ -559,7 +564,7 @@ struct PrintVisitor : TypeManager::Visitor } else { - if(member.bitSize != type.sizeFUCK) + if(member.bitfield) 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()); @@ -596,7 +601,10 @@ struct PrintVisitor : TypeManager::Visitor td.addr = mAddr; td.offset = mOffset; td.id = type.primitive; - td.size = member.bitSize != -1 ? member.bitSize : type.sizeFUCK; + td.size = member.bitSize; + if(td.size == -1) + __debugbreak(); + td.callback = cbPrintPrimitive; td.userdata = nullptr; mNode = GuiTypeAddNode(mParents.empty() ? nullptr : parent().node, &td); diff --git a/src/dbg/types.cpp b/src/dbg/types.cpp index e21e3ef2..4638e7b6 100644 --- a/src/dbg/types.cpp +++ b/src/dbg/types.cpp @@ -109,7 +109,7 @@ bool TypeManager::AddEnumMember(const std::string & parent, const std::string & return true; } -bool TypeManager::AddStructMember(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, bool isBitfield) { if(!isDefined(type) && !validPtr(type)) return false; @@ -118,7 +118,7 @@ bool TypeManager::AddStructMember(const std::string & parent, const std::string return false; // cannot have bit field array - if(bitSize % 8 != 0 && arrsize != 0) + if(isBitfield && arrsize != 0) return false; // cannot be pointer and bitfield @@ -140,20 +140,12 @@ bool TypeManager::AddStructMember(const std::string & parent, const std::string int typeSize; if(arrsize != 0) - { - // is an array typeSize = Sizeof(type) * arrsize; - } else - { - if(bitSize != -1) - typeSize = bitSize; - else - typeSize = Sizeof(type); - } + typeSize = Sizeof(type); // cannot have a bitfield greater than typeSize - if(bitSize != -1 && bitSize > typeSize) + if(isBitfield && bitSize > typeSize) return false; Member m; @@ -162,7 +154,8 @@ bool TypeManager::AddStructMember(const std::string & parent, const std::string m.type = type; m.assignedType = type; m.offsetFUCK = bitOffset; - m.bitSize = m.bitSize != typeSize ? bitSize : typeSize; + m.bitSize = isBitfield ? bitSize : typeSize; + m.bitfield = isBitfield; if(bitOffset >= 0 && !s.isUnion) //user-defined offset { @@ -180,7 +173,7 @@ bool TypeManager::AddStructMember(const std::string & parent, const std::string } else { - s.sizeFUCK += typeSize; + s.sizeFUCK += m.bitSize; } s.members.push_back(m); @@ -189,7 +182,7 @@ bool TypeManager::AddStructMember(const std::string & parent, const std::string bool TypeManager::AppendStructMember(const std::string & type, const std::string & name, int arrsize, int offset) { - return AddStructMember(laststruct, type, name, arrsize, offset, -1); + return AddStructMember(laststruct, type, name, arrsize, offset, -1, false); } bool TypeManager::AppendStructPadding(const std::string & parent, int targetOffset) @@ -225,6 +218,7 @@ bool TypeManager::AppendStructPadding(const std::string & parent, int targetOffs { Member pad; pad.type = "char"; + pad.bitSize = bitPadding; pad.arrsize = bitPadding / 8; // can just add byte padding @@ -632,7 +626,7 @@ 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.AddStructMember(parent, type, name, arrsize, offset, -1); + return typeManager.AddStructMember(parent, type, name, arrsize, offset, -1, false); } bool AppendMember(const std::string & type, const std::string & name, int arrsize, int offset) @@ -751,6 +745,7 @@ static void loadStructUnions(const JSON suroot, std::vector & struc curMember.name = name; curMember.arrsize = json_default_int(valj, "arrsize", 0); curMember.bitSize = json_default_int(valj, "bitSize", -1); + curMember.bitfield = json_boolean_value(json_object_get(valj, "bitfield")); curMember.offsetFUCK = json_default_int(valj, "offset", -1); if(curMember.offsetFUCK != -1) @@ -922,7 +917,7 @@ void LoadModel(const std::string & owner, Model & model) const auto suggestedSize = su.sizeFUCK; for(auto & member : su.members) { - auto success = typeManager.AddStructMember(su.name, member.type, member.name, member.arrsize, member.offsetFUCK, member.bitSize); + auto success = typeManager.AddStructMember(su.name, member.type, member.name, member.arrsize, member.offsetFUCK, member.bitSize, member.bitfield); if(!success) { //TODO properly handle errors diff --git a/src/dbg/types.h b/src/dbg/types.h index 6ff457b0..79736f12 100644 --- a/src/dbg/types.h +++ b/src/dbg/types.h @@ -44,6 +44,7 @@ namespace Types int arrsize = 0; //Number of elements if Member is an array int bitSize = -1; //Bitfield size + bool bitfield = false; int offsetFUCK = -1; //Member offset (only stored for reference) }; @@ -113,7 +114,7 @@ namespace Types 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 AddStructMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize, int bitOffset, int bitSize); + bool AddStructMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize, int bitOffset, int bitSize, bool isBitfield); 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,