Closed abelbriggs1 closed 8 months ago
I was just thinking about this yesterday, odd. I never got around to implementing support for importing typedefs in the Ghidra importer, but I could certainly have a go now.
I've implemented the feature.
Can you help me test it by trying out this unstable build? https://github.com/chaoticgd/ghidra-emotionengine-reloaded/releases/download/unstable/ghidra_10.4_PUBLIC_20231020_ghidra-emotionengine-reloaded.zip
In case anyone is interested: The main reason I didn't implement support for typedefs originally is just that typedefs aren't a first-class citizen in STABS (or C/C++ ASTs for that matter), they're just a storage class modifier. In Ghidra typedefs actually have their own DataTypeImpl subclass.
I've implemented the feature.
Can you help me test it by trying out this unstable build? https://github.com/chaoticgd/ghidra-emotionengine-reloaded/releases/download/unstable/ghidra_10.4_PUBLIC_20231020_ghidra-emotionengine-reloaded.zip
Thanks, this does indeed allow typedefs to be imported with no issue!
As a quick aside, while verifying that this worked, I noticed that bit fields also are not imported. I'm currently taking a stab at implementing that, and it seems to be going alright - I have basic bit fields like this importing without issue:
struct _hierhead { // 0x4
/* 0x0:0 */ unsigned int opcode : 6;
/* 0x0:6 */ unsigned int isRelocated : 1;
/* 0x0:7 */ unsigned int id2 : 11;
/* 0x2:2 */ unsigned int id1 : 14;
};
I'm only having some issues with a couple of very strange bitfields, where some members don't have the bitfield tag for some reason:
// warning: multiple differing types with the same name (#379, size not equal)
typedef union { // 0x8
/* 0x0 */ FLO_type value;
/* 0x0 */ fractype value_raw;
/* 0x0 */ halffractype words[2];
/* 0x0 */ struct { // 0x8
/* 0x0 */ fractype fraction;
/* 0x6:4 */ unsigned int exp : 11;
/* 0x7:7 */ unsigned int sign : 1;
} bits;
} FLO_union_type;
But I don't think this is CCC or ghidra-emotionengine-reloaded
's fault - more likely a bug in GCC which didn't set the bit field
tag on those members.
Glad to hear the initial issue has been resolved.
As for the bitfields, the problem is that STABS doesn't even have a "bit field tag"; it has to be inferred from the offset in bits/size in bits compared to that of the underlying type. It's not immediately clear to me if it would be possible to improve the heuristic ccc uses for detecting bitfields, but since it currently works in almost all cases I think it's perfectly fine to keep it as it is.
If it's helpful the current logic for detecting bitfields is here: https://github.com/chaoticgd/ccc/blob/b873d5511d8c9bd3d093f74c55fd4455fe29bd1f/ccc/ast.cpp#L318
Since I know STABS syntax can be a bit hard to read if you're not familiar with it, I've also manually formatted the relevant stab strings if that's at all useful:
unsigned int:t4=r1;000000000000000000000000;000000000000037777777777;
USItype:t26=4
fractype:t28=26
FLO_union_type:t38=39=
u4
value:30,0,32;
value_raw:28,0,32;
bits:40=
s4
fraction:28,0,23;
exp:4,23,8;
sign:4,31,1;
;
,0,32;
;
Okay I've figured out what the bug was. The bitfield code wasn't resolving stabs references properly. I'll probably put out a v1.3 release of stdump so we can include it with ghidra-emotionengine-reloaded releases shortly (edit: after this is all resolved, obviously).
Thanks - that fix to CCC did the trick!
I've opened a PR for bitfield import support - feel free to review at your leisure.
PR merged.
First, thanks for all your work in maintaining CCC and this extension - both have been very helpful!
I'm currently analyzing a binary (
[SCUS-97101] Twisted Metal: Black (NTSC)
) which contains many debug symbols (functions, globals, C structs). There are quite a few C structs which aretypedef
d to be a different name. An example looks like:However, when I import the binary into Ghidra and run the
STABS
analyzer on the binary, many of these typedefs are substituted for their underlying types, and the typedefs are completely lost (and not imported into Ghidra).It seems like CCC's
stdump
is correctly parsing the typedefs, sincestdump json SCUS_971.01
produces JSON with the typedefs included:Would you happen to know what's causing this behavior and how it can be mitigated? I'm not particularly familiar with the code, but I can try to submit a patch if I can get a general idea of what might be happening.
Thanks!