Read prototype arg counts through one version-compat helper

This commit is contained in:
phix33 authored and pancake committed 2026-09-16 14:20:18 +08:00
1 parent 5884d67ca0
commit ebd12d2536
4 files changed
+45 -6

No files matched your search

+3 -1
View File
@@ -4,6 +4,7 @@
#include "PcodeFixupPreprocessor.h"
#include "R2LoadImage.h"
#include "R2FlagCompat.h"
#include "R2TypeCompat.h"
#include "R2TypeFactory.h"
#include "R2Utils.h"
@@ -324,7 +325,8 @@ static bool parse_variadic_sig(Sdb *tdb, const char *callee, VariadicSig &sig) {
}
bool ok = false;
if (r_type_func_exist (tdb, fname)) {
const int argc = r_type_func_args_count (tdb, fname);
int argc = 0;
countargs (tdb, fname, &argc);
for (int i = 0; i < argc; i++) {
// the vararg slot is stored as `,...` so the "..." marker lands in the name, not the type
const char *an = r_type_func_args_name (tdb, fname, i);
+6 -4
View File
@@ -3,6 +3,7 @@
#include "R2Architecture.h"
#include "R2FlagCompat.h"
#include "R2TypeCompat.h"
#include "R2TypeFactory.h"
#include "R2Scope.h"
@@ -407,7 +408,8 @@ static void processFunctionSignature(
if (fname && r_type_func_exist (tdb, fname)) {
// a cc key marks an afs-set prototype; auto-inferred and library types have none
explicit_proto = sdb_const_get (tdb, ("func." + std::string (fname) + ".cc").c_str (), nullptr) != nullptr;
const int argc = r_type_func_args_count (tdb, fname);
int argc = 0;
countargs (tdb, fname, &argc);
for (int i = 0; i < argc; i++) {
char *arg_type = r_type_func_args_type (tdb, fname, i);
if (!arg_type) {
@@ -538,11 +540,11 @@ static void processFunctionSignature(
static bool protoHasNoArgs(RCore *core, const char *name) {
Sdb *tdb = core->anal->sdb_types;
char *key = r_type_func_key (tdb, name);
int argc = 0;
// a missing args key is an unknown prototype, not an empty one
const char *args = key? sdb_const_getf (tdb, nullptr, "func.%s.args", key): nullptr;
const bool noArgs = key && countargs (tdb, key, &argc) && !argc;
free (key);
char *end = nullptr;
return args && *args == '0' && !strtoull (args, &end, 0) && !*end;
return noArgs;
}
// Ghidra does active param recovery unless input is locked, so a no-arg noreturn (eg __stack_chk_fail) would otherwise get a live caller reg as a phantom arg
+33
View File
@@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: 2026 pancake
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef R2GHIDRA_R2TYPECOMPAT_H
#define R2GHIDRA_R2TYPECOMPAT_H
#include <cctype>
#include <r_util.h>
#include <r_lib.h>
// abi 143 made the count a query: a missing or malformed args key is unknown
static inline bool countargs(Sdb *tdb, const char *name, int *argc) {
#if R2_ABIVERSION >= 143
return r_type_func_args_count (tdb, name, argc);
#else
while (!sdb_const_get (tdb, name, 0) && r_str_startswith (name, "__")) {
name += 2;
}
const char *args = sdb_const_getf (tdb, nullptr, "func.%s.args", name);
if (!args || !isdigit ((ut8)*args)) {
return false;
}
char *end;
const ut64 count = strtoull (args, &end, 0);
if (*end || count > ST32_MAX) {
return false;
}
*argc = (int)count;
return true;
#endif
}
#endif // R2GHIDRA_R2TYPECOMPAT_H
+3 -1
View File
@@ -3,6 +3,7 @@
#include "R2TypeFactory.h"
#include "R2Architecture.h"
#include "R2TypeCompat.h"
#include "fspec.hh"
#include <r_core.h>
@@ -638,7 +639,8 @@ Datatype *R2TypeFactory::queryR2Function(const string &n, std::set<std::string>
Sdb *sdb = core->anal->sdb_types;
const char *ret = r_type_func_ret(sdb, n.c_str());
int arg_count = r_type_func_args_count(sdb, n.c_str());
int arg_count = 0;
countargs(sdb, n.c_str(), &arg_count);
if (!ret && arg_count <= 0) {
return nullptr;
}