Skip to content

Commit d3c008e

Browse files
committed
Fix return storage and struct parameters
1 parent 0e73489 commit d3c008e

File tree

5 files changed

+78
-10
lines changed

5 files changed

+78
-10
lines changed

bindings/2.2074/Cocos2d.bro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4295,9 +4295,9 @@ void kmGLMatrixMode(unsigned int) = m1 0x1aba44, imac 0x1f5f60, ios 0x16bc08;
42954295
[[link(win, android)]]
42964296
void kmGLLoadIdentity() = m1 0x1abafc, imac 0x1f6010, ios 0x16bcc0;
42974297
// [[link(win, android)]] // TODO: Figure this out
4298-
// const kmMat4* kmMat4OrthographicProjection(kmMat4*, float, float, float, float, float, float) = m1 0x1abafc, imac 0x3c1240, ios 0x3ab750;
4298+
// kmMat4* const kmMat4OrthographicProjection(kmMat4*, float, float, float, float, float, float) = m1 0x1abafc, imac 0x3c1240, ios 0x3ab750;
42994299
[[link(win, android)]]
4300-
void kmGLMultMatrix(kmMat4 const*) = m1 0x1abb60, imac 0x1f6070, ios 0x16bd24;
4300+
void kmGLMultMatrix(const kmMat4*) = m1 0x1abb60, imac 0x1f6070, ios 0x16bd24;
43014301

43024302
[[link(win, android)]]
43034303
class DS_Dictionary {

bindings/2.2074/GeometryDash.bro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6134,7 +6134,7 @@ class FMODAudioEngine : cocos2d::CCNode {
61346134
void setChannelPitch(int, AudioTargetType, float);
61356135
void setChannelVolume(int, AudioTargetType, float) = imac 0x3d0f40;
61366136
void setChannelVolumeMod(int, AudioTargetType, float) = win 0x58f80;
6137-
void setEffectsVolume(float volume) = win inline, imac 0x3d48d0, m1 0x35ad90, ios 0x1402a {
6137+
void setEffectsVolume(float volume) = win inline, imac 0x3d48d0, m1 0x35ad90, ios 0x1402a0 {
61386138
m_sfxVolume = volume;
61396139
if (m_globalChannel) m_globalChannel->setVolume(volume);
61406140
}

scripts/ghidra/ScriptWrapper.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,8 @@ Signature getBromaSignature(Broma.Function fun, Platform platform, boolean ignor
473473
// Parse args
474474
List<Variable> bromaParams = new ArrayList<Variable>();
475475
// Add `this` arg
476-
if (fun.dispatch.isEmpty() || !fun.dispatch.get().value.contains("static")) {
476+
boolean hasThis = fun.dispatch.isEmpty() || !fun.dispatch.get().value.contains("static");
477+
if (hasThis && platform != Platform.ANDROID32 && platform != Platform.MAC_INTEL) {
477478
bromaParams.add(new ParameterImpl(
478479
"this",
479480
addOrGetType(Broma.Type.ptr(fun.parent.broma, fun.parent.name.value), platform),
@@ -483,25 +484,42 @@ Signature getBromaSignature(Broma.Function fun, Platform platform, boolean ignor
483484
}
484485
// Parse return type, or null if this is a destructor
485486
ReturnParameterImpl bromaRetType = null;
487+
boolean hasStructReturn = false;
486488
if (fun.returnType.isPresent() && !ignoreReturnType) {
487489
var type = addOrGetType(fun.returnType.get(), platform);
488490
// Struct return
489491
if (type instanceof Composite) {
492+
hasStructReturn = true;
490493
type = new PointerDataType(type);
491-
bromaParams.add(new ParameterImpl("__return", type, wrapped.getCurrentProgram(), SourceType.USER_DEFINED));
494+
if (platform != Platform.ANDROID64 && platform != Platform.MAC_ARM && platform != Platform.IOS) {
495+
bromaParams.add(new ParameterImpl("__return", type, wrapped.getCurrentProgram(), SourceType.USER_DEFINED));
496+
}
492497
}
493498
bromaRetType = new ReturnParameterImpl(type, wrapped.getCurrentProgram());
494499
}
500+
// Add `this` arg (Intel macOS / 32-bit Android)
501+
if (hasThis && (platform == Platform.ANDROID32 || platform == Platform.MAC_INTEL)) {
502+
bromaParams.add(new ParameterImpl(
503+
"this",
504+
addOrGetType(Broma.Type.ptr(fun.parent.broma, fun.parent.name.value), platform),
505+
wrapped.getCurrentProgram(),
506+
SourceType.USER_DEFINED
507+
));
508+
}
495509
// Params
496510
for (var param : fun.params) {
511+
var paramType = addOrGetType(param.type, platform);
497512
bromaParams.add(new ParameterImpl(
498513
param.name.map(p -> p.value).orElse(null),
499-
addOrGetType(param.type, platform),
514+
paramType instanceof Composite ? new PointerDataType(paramType) : paramType,
500515
wrapped.getCurrentProgram(),
501516
SourceType.USER_DEFINED
502517
));
503518
}
504-
return new Signature(bromaRetType, bromaParams);
519+
Signature bromaSig = new Signature(bromaRetType, bromaParams);
520+
bromaSig.memberFunction = hasThis;
521+
bromaSig.returnsStruct = hasStructReturn;
522+
return bromaSig;
505523
}
506524

507525
void askContinue(String title, String fmt, Object... args) throws Exception {

scripts/ghidra/Signature.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
public class Signature {
88
public Optional<Variable> returnType;
99
public List<Variable> parameters;
10+
public boolean memberFunction = false;
11+
public boolean returnsStruct = false;
1012

1113
Signature(Variable ret, List<Variable> params) {
1214
returnType = Optional.ofNullable(ret);

scripts/ghidra/SyncBromaScript.java

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import ghidra.program.model.data.Undefined;
3232
import ghidra.program.model.data.VoidDataType;
3333
import ghidra.program.model.listing.Function.FunctionUpdateType;
34+
import ghidra.program.model.listing.Parameter;
35+
import ghidra.program.model.listing.ParameterImpl;
3436
import ghidra.program.model.listing.Variable;
3537
import ghidra.program.model.listing.VariableStorage;
3638
import ghidra.program.model.symbol.SourceType;
@@ -279,8 +281,11 @@ private SignatureImport importSignatureFromBroma(Address addr, Broma.Function fu
279281
) {
280282
signatureConflict = true;
281283
}
282-
// Keep existing Ghidra name for args without names in Broma
283-
else if (bromaParam.getName() == null && param.getName() != null) {
284+
// Keep existing Ghidra name for args without names in Broma (Making sure to not include any duplicates)
285+
else if (
286+
bromaParam.getName() == null && param.getName() != null &&
287+
!bromaSig.parameters.subList(0, i).stream().anyMatch(p -> p.getName() != null && p.getName().equals(param.getName()))
288+
) {
284289
bromaParam.setName(param.getName(), SourceType.USER_DEFINED);
285290
}
286291
}
@@ -390,10 +395,24 @@ else if (conv == CConv.OPTCALL && i == 1 && !(type instanceof Composite)) {
390395
updateType = FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS;
391396
}
392397

398+
// Check for already-existing parameter names
399+
for (var existingParam : data.getParameters()) {
400+
for (var bromaParam : bromaSig.parameters) {
401+
if (!existingParam.isAutoParameter() && existingParam.getName() != null && existingParam.getName().equals(bromaParam.getName())) {
402+
existingParam.setName(null, SourceType.USER_DEFINED);
403+
}
404+
}
405+
}
406+
407+
var conventionName = conv.getGhidraName();
408+
if (bromaSig.returnsStruct && bromaSig.memberFunction && (args.platform == Platform.ANDROID32 || args.platform == Platform.MAC_INTEL)) {
409+
conventionName = args.platform == Platform.MAC_INTEL ? "__stdcall" : "__cdecl";
410+
}
411+
393412
// Apply new signature
394413
try {
395414
data.updateFunction(
396-
conv.getGhidraName(),
415+
conventionName,
397416
bromaSig.returnType.orElse(null),
398417
updateType,
399418
true,
@@ -404,6 +423,35 @@ else if (conv == CConv.OPTCALL && i == 1 && !(type instanceof Composite)) {
404423
throw new Error("Died on: " + fullName + " with " + e.getMessage());
405424
}
406425

426+
// Set struct return storage for ARM64
427+
if (bromaSig.returnsStruct && (args.platform == Platform.ANDROID64 || args.platform == Platform.MAC_ARM || args.platform == Platform.IOS)) {
428+
var newParams = new ArrayList<Parameter>(List.of(data.getParameters()));
429+
var foundReturn = newParams.stream().filter(p -> p.getName() != null && p.getName().equals("__return")).findFirst();
430+
if (foundReturn.isPresent()) {
431+
foundReturn.get().setName(null, SourceType.USER_DEFINED);
432+
}
433+
newParams.add(0, new ParameterImpl(
434+
"__return",
435+
data.getReturnType(),
436+
new VariableStorage(currentProgram, currentProgram.getRegister("x8")),
437+
currentProgram,
438+
SourceType.USER_DEFINED
439+
));
440+
try {
441+
data.updateFunction(
442+
"__cdecl",
443+
bromaSig.returnType.orElse(null),
444+
FunctionUpdateType.CUSTOM_STORAGE,
445+
true,
446+
SourceType.USER_DEFINED,
447+
newParams.toArray(Variable[]::new)
448+
);
449+
} catch (Exception e) {
450+
throw new Error("Died on: " + fullName + " with " + e.getMessage());
451+
}
452+
data.setReturn(data.getReturnType(), new VariableStorage(currentProgram, currentProgram.getRegister("x0")), SourceType.USER_DEFINED);
453+
}
454+
407455
// Set return type storage for custom cconvs
408456
if (shouldReorderParams && bromaSig.returnType.isPresent()) {
409457
var ret = bromaSig.returnType.get();

0 commit comments

Comments
 (0)