Handle Large Bit Fields
What happened?
We always set bit fields to unsigned int, but that fails when we have a bit field larger than 32 bits.
Width of bit-field 'i' (128 bits) exceeds the width of its type (32 bits)
How can we reproduce this?
Decompile this:
@implementation C : NSObject {
__int128 i : 128;
}
@end
go-macho version
v1.1.208
Search
- [x] I did search for other open and closed issues before opening this
Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Additional context
No response
I noticed this as well. There's also the NSNumber (I think) ex you found, where VERY annoyingly the first bitfield field is encoded as b8 but the src says it's signed int x:8 etc
There's no way to tell that it's signed just how many bits/wide it is. (so no way to have a perfect decode)
To solve this issue however is going to be kinda gross, where I'll have to parse ALL the properties or stucts fields etc and then go BACK to determine the orig size of int. Shouldn't be too hard, just gross
It was NSDecimalNumber. Yeah, it sucks the encoded objc type is only b8.
- ipsw Header:
@interface NSDecimalNumber : NSNumber {
/* instance variables */
unsigned int x :8 _exponent;
unsigned int x :4 _length;
unsigned int x :1 _isNegative;
unsigned int x :1 _isCompact;
unsigned int x :1 _reserved;
unsigned int x :1 _hasExternalRefCount;
unsigned int x :16 _refs;
unsigned short * _mantissa;
}
- Official Apple SDK Header:
@interface NSDecimalNumber : NSNumber {
@private
signed int _exponent:8;
unsigned int _length:4;
unsigned int _isNegative:1;
unsigned int _isCompact:1;
unsigned int _reserved:1;
unsigned int _hasExternalRefCount:1;
unsigned int _refs:16;
unsigned short _mantissa[];
}
We could technically omit the sign of the integer and let the user decide...
In the C programming language, the width of a bit-field cannot exceed the width of the underlying type, and WHETHER INT BIT-FIELDS THAT ARE NOT EXPLICITLY SIGNED OR UNSIGNED ARE SIGNED OR UNSIGNED IS IMPLEMENTATION-DEFINED. For example, int b:3; may have the range of values 0..7 or -4..3 in C, but only the latter choice is allowed in C++.
From: https://en.cppreference.com/w/cpp/language/bit_field
This is interesting: https://github.com/apple-oss-distributions/clang/blob/rel/clang-800/src/tools/clang/lib/AST/ASTContext.cpp#L5536-L5550
I wished LLVM had stuck with the GNU version rather than the NeXT version...
This is interesting: https://github.com/apple-oss-distributions/clang/blob/rel/clang-800/src/tools/clang/lib/AST/ASTContext.cpp#L5536-L5550
I wished LLVM had stuck with the GNU version rather than the NeXT version...
lol, yes, that's MUCH nicer 😞