diff --git a/librz/analysis/analysis.c b/librz/analysis/analysis.c index c1899a9213..7e275836d3 100644 --- a/librz/analysis/analysis.c +++ b/librz/analysis/analysis.c @@ -282,6 +282,7 @@ RZ_API bool rz_analysis_set_bits(RzAnalysis *analysis, int bits) { int v = rz_analysis_archinfo(analysis, RZ_ANALYSIS_ARCHINFO_ALIGN); analysis->pcalign = RZ_MAX(0, v); rz_type_db_set_bits(analysis->typedb, bits); + rz_type_db_set_address_bits(analysis->typedb, rz_analysis_get_address_bits(analysis)); if (!is_hack) { char *types_dir = rz_path_system(RZ_SDB_TYPES); rz_type_db_reload(analysis->typedb, types_dir); diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index 1f8b955828..8cab742663 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -20,6 +20,7 @@ RZ_LIB_VERSION_HEADER(rz_type); typedef struct rz_type_target_t { char *cpu; int bits; + int addr_bits; ///< size of a pointer if > 0, otherwise bits is used. char *os; bool big_endian; const char *default_type; @@ -230,6 +231,7 @@ RZ_API bool rz_type_db_load_sdb_str(RzTypeDB *typedb, RZ_NONNULL const char *str RZ_API bool rz_type_db_load_callables_sdb(RzTypeDB *typedb, RZ_NONNULL const char *path); RZ_API bool rz_type_db_load_callables_sdb_str(RzTypeDB *typedb, RZ_NONNULL const char *str); RZ_API void rz_type_db_set_bits(RzTypeDB *typedb, int bits); +RZ_API void rz_type_db_set_address_bits(RzTypeDB *typedb, int addr_bits); RZ_API void rz_type_db_set_os(RzTypeDB *typedb, const char *os); RZ_API void rz_type_db_set_cpu(RzTypeDB *typedb, const char *cpu); RZ_API void rz_type_db_set_endian(RzTypeDB *typedb, bool big_endian); diff --git a/librz/type/type.c b/librz/type/type.c index 2318b5a2f5..e90908e081 100644 --- a/librz/type/type.c +++ b/librz/type/type.c @@ -148,6 +148,21 @@ RZ_API void rz_type_db_set_bits(RzTypeDB *typedb, int bits) { set_default_type(typedb->target, bits); } +/** + * \brief Set the RzType target adress size + * + * Important for calculating some types size, especially + * pointers's size. + * + * \param typedb RzTypeDB instance + * \param bits size of an address in bits. If <= 0, then + * the value from rz_type_db_set_bits() is used. + */ +RZ_API void rz_type_db_set_address_bits(RzTypeDB *typedb, int addr_bits) { + rz_return_if_fail(typedb); + typedb->target->addr_bits = addr_bits; +} + /** * \brief Set the RzType target architecture operating system * @@ -194,9 +209,7 @@ RZ_API void rz_type_db_set_endian(RzTypeDB *typedb, bool big_endian) { * \param typedb RzTypeDB instance */ RZ_API ut8 rz_type_db_pointer_size(const RzTypeDB *typedb) { - // TODO: Handle more special cases where the pointer - // size is different from the target bitness - return typedb->target->bits; + return typedb->target->addr_bits > 0 ? typedb->target->addr_bits : typedb->target->bits; } /** diff --git a/test/db/cmd/types b/test/db/cmd/types index e33b788b5c..a93cd9be5b 100644 --- a/test/db/cmd/types +++ b/test/db/cmd/types @@ -188,52 +188,54 @@ pdr~JNI? EOF EXPECT=<