mirror of
https://github.com/rizinorg/rizin.git
synced 2026-10-12 02:21:57 +00:00
Fix stack location in composite
This commit is contained in:
@@ -39,7 +39,7 @@ static bool function_from_die(
|
||||
RZ_BORROW RZ_IN RZ_NONNULL Context *ctx,
|
||||
RZ_BORROW RZ_IN RZ_NONNULL const RzBinDwarfDie *die);
|
||||
|
||||
static void parse_die(Context *ctx, RzBinDwarfDie *die);
|
||||
static void die_parse(Context *ctx, RzBinDwarfDie *die);
|
||||
|
||||
/* For some languages linkage name is more informative like C++,
|
||||
but for Rust it's rubbish and the normal name is fine */
|
||||
@@ -735,10 +735,10 @@ static RzBaseType *RzBaseType_from_die(Context *ctx, const RzBinDwarfDie *die) {
|
||||
btype->name, die->offset);
|
||||
}
|
||||
|
||||
RzPVector *btypes = ht_pp_find(ctx->analysis->debug_info->base_type_by_name, btype->name, NULL);
|
||||
RzPVector *btypes = ht_pp_find(ctx->analysis->debug_info->base_types_by_name, btype->name, NULL);
|
||||
if (!btypes) {
|
||||
btypes = rz_pvector_new(NULL);
|
||||
ht_pp_insert(ctx->analysis->debug_info->base_type_by_name, btype->name, btypes);
|
||||
ht_pp_insert(ctx->analysis->debug_info->base_types_by_name, btype->name, btypes);
|
||||
rz_pvector_push(btypes, btype);
|
||||
} else {
|
||||
void **it;
|
||||
@@ -1158,7 +1158,7 @@ static bool struct_union_children_parse(
|
||||
// we take only direct descendats of the structure
|
||||
if (!(child_die->depth == die->depth + 1 &&
|
||||
child_die->tag == DW_TAG_member)) {
|
||||
parse_die(ctx, child_die);
|
||||
die_parse(ctx, child_die);
|
||||
continue;
|
||||
}
|
||||
RzTypeStructMember member = { 0 };
|
||||
@@ -1217,7 +1217,7 @@ static bool enum_children_parse(
|
||||
RzBinDwarfDie *child_die = *it;
|
||||
if (!(child_die->depth == die->depth + 1 &&
|
||||
child_die->tag == DW_TAG_enumerator)) {
|
||||
parse_die(ctx, child_die);
|
||||
die_parse(ctx, child_die);
|
||||
continue;
|
||||
}
|
||||
RzTypeEnumCase cas = { 0 };
|
||||
@@ -1354,18 +1354,18 @@ static RzBinDwarfLocation *location_parse(
|
||||
}
|
||||
if (rz_pvector_len(&loclist->entries) > 1) {
|
||||
return location_list_parse(ctx, loclist, fn);
|
||||
} else if (rz_pvector_len(&loclist->entries) == 1) {
|
||||
}
|
||||
if (rz_pvector_len(&loclist->entries) == 1) {
|
||||
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 0);
|
||||
return rz_bin_dwarf_location_from_block(entry->expression, ctx->dw, ctx->unit, fn);
|
||||
} else {
|
||||
RzBinDwarfLocation *loc = RZ_NEW0(RzBinDwarfLocation);
|
||||
if (!loc) {
|
||||
return NULL;
|
||||
}
|
||||
loc->kind = RzBinDwarfLocationKind_EMPTY;
|
||||
loc->encoding = ctx->unit->hdr.encoding;
|
||||
return loc;
|
||||
}
|
||||
RzBinDwarfLocation *loc = RZ_NEW0(RzBinDwarfLocation);
|
||||
if (!loc) {
|
||||
return NULL;
|
||||
}
|
||||
loc->kind = RzBinDwarfLocationKind_EMPTY;
|
||||
loc->encoding = ctx->unit->hdr.encoding;
|
||||
return loc;
|
||||
err_find:
|
||||
RZ_LOG_ERROR("Location parse failed 0x%" PFMT64x " <Cannot find loclist>\n", offset);
|
||||
return NULL;
|
||||
@@ -1462,7 +1462,7 @@ static bool function_children_parse(
|
||||
rz_pvector_foreach (children, it) {
|
||||
RzBinDwarfDie *child_die = *it;
|
||||
if (child_die->depth != die->depth + 1) {
|
||||
parse_die(ctx, child_die);
|
||||
die_parse(ctx, child_die);
|
||||
continue;
|
||||
}
|
||||
RzAnalysisDwarfVariable v = { 0 };
|
||||
@@ -1662,7 +1662,7 @@ static bool variable_from_die(
|
||||
return result;
|
||||
}
|
||||
|
||||
static void parse_die(Context *ctx, RzBinDwarfDie *die) {
|
||||
static void die_parse(Context *ctx, RzBinDwarfDie *die) {
|
||||
if (set_u_contains(ctx->analysis->debug_info->visited, die->offset)) {
|
||||
return;
|
||||
}
|
||||
@@ -1690,6 +1690,12 @@ static void parse_die(Context *ctx, RzBinDwarfDie *die) {
|
||||
}
|
||||
}
|
||||
|
||||
static RzBinDwarfDie *die_next(RzBinDwarfDie *die, RzBinDWARF *dw) {
|
||||
return (die->sibling > die->offset)
|
||||
? ht_up_find(dw->info->die_by_offset, die->sibling, NULL)
|
||||
: die + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parses type and function information out of DWARF entries
|
||||
* and stores them to analysis->debug_info
|
||||
@@ -1717,10 +1723,8 @@ RZ_API void rz_analysis_dwarf_preprocess_info(
|
||||
ctx.unit = unit;
|
||||
for (RzBinDwarfDie *die = rz_vector_head(&unit->dies);
|
||||
die && (ut8 *)die < (ut8 *)unit->dies.a + unit->dies.len * unit->dies.elem_size;
|
||||
(die->sibling > die->offset)
|
||||
? die = ht_up_find(dw->info->die_by_offset, die->sibling, NULL)
|
||||
: ++die) {
|
||||
parse_die(&ctx, die);
|
||||
die = die_next(die, dw)) {
|
||||
die_parse(&ctx, die);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1758,7 +1762,7 @@ static bool store_base_type(void *u, const void *k, const void *v) {
|
||||
RzAnalysis *analysis = u;
|
||||
const char *name = k;
|
||||
RzPVector *types = (RzPVector *)v;
|
||||
ut32 len = rz_pvector_len(types);
|
||||
const ut32 len = rz_pvector_len(types);
|
||||
if (len == 0) {
|
||||
RZ_LOG_WARN("BaseType %s has nothing", name);
|
||||
} else if (len == 1) {
|
||||
@@ -1792,7 +1796,6 @@ static bool store_base_type(void *u, const void *k, const void *v) {
|
||||
db_save_renamed(analysis->typedb, rz_base_type_clone(b), newname);
|
||||
} else {
|
||||
RZ_LOG_WARN("BaseType: same name [%s] type count is more than 3\n", name);
|
||||
goto beach;
|
||||
}
|
||||
beach:
|
||||
return true;
|
||||
@@ -1817,7 +1820,7 @@ static bool store_callable(void *u, ut64 k, const void *v) {
|
||||
RZ_API void rz_analysis_dwarf_process_info(RzAnalysis *analysis, RzBinDWARF *dw) {
|
||||
rz_return_if_fail(analysis && dw);
|
||||
rz_analysis_dwarf_preprocess_info(analysis, dw);
|
||||
ht_pp_foreach(analysis->debug_info->base_type_by_name, store_base_type, (void *)analysis);
|
||||
ht_pp_foreach(analysis->debug_info->base_types_by_name, store_base_type, (void *)analysis);
|
||||
ht_up_foreach(analysis->debug_info->callable_by_offset, store_callable, (void *)analysis);
|
||||
}
|
||||
|
||||
@@ -2056,7 +2059,7 @@ RZ_API RzAnalysisDebugInfo *rz_analysis_debug_info_new() {
|
||||
debug_info->type_by_offset = ht_up_new(NULL, HtUP_RzType_free, NULL);
|
||||
debug_info->callable_by_offset = ht_up_new(NULL, HtUP_RzCallable_free, NULL);
|
||||
debug_info->base_type_by_offset = ht_up_new(NULL, HtUP_RzBaseType_free, NULL);
|
||||
debug_info->base_type_by_name = ht_pp_new(NULL, HtPP_RzPVector_free, NULL);
|
||||
debug_info->base_types_by_name = ht_pp_new(NULL, HtPP_RzPVector_free, NULL);
|
||||
debug_info->visited = set_u_new();
|
||||
return debug_info;
|
||||
}
|
||||
@@ -2075,7 +2078,7 @@ RZ_API void rz_analysis_debug_info_free(RzAnalysisDebugInfo *debuginfo) {
|
||||
ht_up_free(debuginfo->type_by_offset);
|
||||
ht_up_free(debuginfo->callable_by_offset);
|
||||
ht_up_free(debuginfo->base_type_by_offset);
|
||||
ht_pp_free(debuginfo->base_type_by_name);
|
||||
ht_pp_free(debuginfo->base_types_by_name);
|
||||
rz_bin_dwarf_free(debuginfo->dw);
|
||||
set_u_free(debuginfo->visited);
|
||||
free(debuginfo);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <rz_util.h>
|
||||
#include <rz_bin_dwarf.h>
|
||||
#include "macro.inc"
|
||||
#include "macro.h"
|
||||
|
||||
typedef struct {
|
||||
ut64 unit_offset;
|
||||
@@ -63,58 +63,10 @@ RZ_IPI void Range_free(RzBinDwarfRange *self);
|
||||
|
||||
RZ_IPI void DebugRngLists_free(RzBinDwarfRngLists *self);
|
||||
|
||||
/// value
|
||||
|
||||
RZ_IPI bool ValueType_from_encoding(DW_ATE encoding, ut64 byte_size, RzBinDwarfValueType *out_type);
|
||||
RZ_IPI bool ValueType_from_entry(RzBinDwarfDie *entry, RzBinDwarfValueType *out);
|
||||
RZ_IPI bool Value_parse_into(
|
||||
RzBinDwarfValue *value, RzBinDwarfValueType value_type, RzBinEndianReader *reader);
|
||||
RZ_IPI RzBinDwarfValueType Value_type(RzBinDwarfValue *ptr);
|
||||
RZ_IPI bool Value_to_u64(RzBinDwarfValue *self, ut64 addr_mask, ut64 *result);
|
||||
RZ_IPI bool Value_from_u64(RzBinDwarfValueType value_type, ut64 value, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_from_f32(RzBinDwarfValueType value_type, float value, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_from_f64(RzBinDwarfValueType value_type, double value, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_convert(RzBinDwarfValue *self, RzBinDwarfValueType typ, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_reinterpret(RzBinDwarfValue *self, RzBinDwarfValueType value_type, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_abs(RzBinDwarfValue *self, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_neg(RzBinDwarfValue *self, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_add(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_sub(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_mul(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_div(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_rem(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_not(RzBinDwarfValue *self, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_and(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_or(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_xor(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_shift_length(RzBinDwarfValue *self, ut64 *result);
|
||||
RZ_IPI bool Value_shl(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_shr(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_shra(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_eq(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_ge(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_gt(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_le(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_lt(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_ne(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI void Value_fini(RzBinDwarfValue *self);
|
||||
RZ_IPI void Value_free(RzBinDwarfValue *self);
|
||||
RZ_IPI RzBinDwarfValue *Value_clone(RzBinDwarfValue *self);
|
||||
RZ_IPI bool Value_clone_into(RzBinDwarfValue *self, RzBinDwarfValue *val);
|
||||
RZ_IPI void Value_dump(
|
||||
const RzBinDwarfValue *self,
|
||||
RzStrBuf *sb,
|
||||
const RzBinDWARFDumpOption *opt);
|
||||
/// op
|
||||
|
||||
#include "value.h"
|
||||
#include "op.h"
|
||||
|
||||
RZ_IPI void rz_bin_dwarf_evaluation_cpy(RzBinDwarfEvaluation *dst, RzBinDwarfEvaluation *src);
|
||||
RZ_IPI void RzBinDwarfEvaluationResult_cpy(RzBinDwarfEvaluationResult *dst, RzBinDwarfEvaluationResult *src);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -422,10 +422,39 @@ RZ_API RZ_OWN RzBinDwarfLocation *rz_bin_dwarf_location_clone(RZ_BORROW RZ_NONNU
|
||||
RzBinDwarfLocation *loc = RZ_NEWCOPY(RzBinDwarfLocation, self);
|
||||
switch (loc->kind) {
|
||||
case RzBinDwarfLocationKind_COMPOSITE:
|
||||
loc->composite = rz_vector_clone(self->composite);
|
||||
loc->composite = rz_vector_clonef(self->composite, (RzVectorItemCpyFunc)RzBinDwarfPiece_cpy);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
RZ_IPI void Location_cpy(Location *dst, Location *src) {
|
||||
rz_return_if_fail(dst && src);
|
||||
memcpy(dst, src, sizeof(Location));
|
||||
switch (src->kind) {
|
||||
case RzBinDwarfLocationKind_BYTES:
|
||||
RzBinDwarfBlock_cpy(&dst->bytes, &src->bytes);
|
||||
break;
|
||||
case RzBinDwarfLocationKind_EVALUATION_WAITING:
|
||||
rz_bin_dwarf_evaluation_cpy(dst->eval_waiting.eval, src->eval_waiting.eval);
|
||||
RzBinDwarfEvaluationResult_cpy(dst->eval_waiting.result, src->eval_waiting.result);
|
||||
break;
|
||||
case RzBinDwarfLocationKind_COMPOSITE:
|
||||
rz_vector_clone_intof(dst->composite, src->composite, (RzVectorItemCpyFunc)RzBinDwarfPiece_cpy);
|
||||
break;
|
||||
case RzBinDwarfLocationKind_LOCLIST:
|
||||
rz_warn_if_reached();
|
||||
break;
|
||||
case RzBinDwarfLocationKind_EMPTY: break;
|
||||
case RzBinDwarfLocationKind_DECODE_ERROR: break;
|
||||
case RzBinDwarfLocationKind_REGISTER: break;
|
||||
case RzBinDwarfLocationKind_REGISTER_OFFSET: break;
|
||||
case RzBinDwarfLocationKind_ADDRESS: break;
|
||||
case RzBinDwarfLocationKind_VALUE: break;
|
||||
case RzBinDwarfLocationKind_IMPLICIT_POINTER: break;
|
||||
case RzBinDwarfLocationKind_CFA_OFFSET: break;
|
||||
case RzBinDwarfLocationKind_FB_OFFSET: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// SPDX-FileCopyrightText: 2023 billow <[email protected]>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef LOCLISTS_H
|
||||
#define LOCLISTS_H
|
||||
|
||||
#include "op.h"
|
||||
|
||||
RZ_IPI void Location_cpy(Location *dst, Location *src);
|
||||
|
||||
#endif // LOCLISTS_H
|
||||
@@ -7,26 +7,20 @@
|
||||
#define MEM_CPY(T, dst, src) rz_mem_copy((dst), sizeof(T), (src), sizeof(T))
|
||||
|
||||
#define OK_OR(x, E) \
|
||||
do { \
|
||||
if (!(x)) { \
|
||||
E; \
|
||||
} \
|
||||
} while (0)
|
||||
if (!(x)) { \
|
||||
E; \
|
||||
}
|
||||
|
||||
#define OK_OR_ERR(x, E) \
|
||||
do { \
|
||||
if (!(x)) { \
|
||||
E; \
|
||||
goto err; \
|
||||
} \
|
||||
} while (0)
|
||||
if (!(x)) { \
|
||||
E; \
|
||||
goto err; \
|
||||
}
|
||||
|
||||
#define AND_DO(x, E) \
|
||||
do { \
|
||||
if ((x)) { \
|
||||
E; \
|
||||
} \
|
||||
} while (0)
|
||||
if ((x)) { \
|
||||
E; \
|
||||
}
|
||||
|
||||
#define RET_FALSE_IF_FAIL(x) OK_OR(x, return false)
|
||||
#define RET_NULL_IF_FAIL(x) OK_OR(x, return NULL)
|
||||
@@ -63,3 +57,8 @@
|
||||
static void Ht##V##_##T##_free(Ht##V##Kv *kv) { \
|
||||
f(kv->value); \
|
||||
}
|
||||
|
||||
#define RZ_VECTOR_FINI_T(T, f) \
|
||||
static void RzVector_##T##_fini(void *v, void *u) { \
|
||||
f(v); \
|
||||
}
|
||||
+129
-71
@@ -32,8 +32,6 @@ static bool RzBinDwarfLocation_move(RzBinDwarfLocation *self, RzBinDwarfLocation
|
||||
case RzBinDwarfLocationKind_LOCLIST:
|
||||
self->loclist = NULL;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -544,7 +542,7 @@ static bool Evaluation_pop(RzBinDwarfEvaluation *self, RzBinDwarfValue *value) {
|
||||
}
|
||||
|
||||
static bool Evaluation_push(RzBinDwarfEvaluation *self, RzBinDwarfValue *value) {
|
||||
bool status = rz_vector_push(&self->stack, value) != NULL;
|
||||
const bool status = rz_vector_push(&self->stack, value) != NULL;
|
||||
if (!status) {
|
||||
Value_fini(value);
|
||||
}
|
||||
@@ -611,8 +609,8 @@ static RzBinDwarfValueType ValueType_from_name(const char *name, ut8 byte_size)
|
||||
}
|
||||
|
||||
static RzBinDwarfValueType ValueType_from_die(
|
||||
RzBinDwarfEvaluation *eval, const RzBinDWARF *dw, UnitOffset offset) {
|
||||
RzBinDwarfDie *die = ht_up_find(dw->info->die_by_offset, eval->unit->offset + offset, NULL);
|
||||
const RzBinDwarfEvaluation *eval, const RzBinDWARF *dw, UnitOffset offset) {
|
||||
const RzBinDwarfDie *die = ht_up_find(dw->info->die_by_offset, eval->unit->offset + offset, NULL);
|
||||
if (!die) {
|
||||
return RzBinDwarfValueType_GENERIC;
|
||||
}
|
||||
@@ -659,24 +657,13 @@ static RzBinDwarfValueType ValueType_from_die(
|
||||
return value_type;
|
||||
}
|
||||
|
||||
static void RzBinDwarfPiece_fini(RzBinDwarfPiece *x) {
|
||||
if (!x) {
|
||||
return;
|
||||
}
|
||||
rz_bin_dwarf_location_free(x->location);
|
||||
}
|
||||
|
||||
static inline ut64 addrmask_from_size(uint8_t size) {
|
||||
static ut64 addrmask_from_size(uint8_t size) {
|
||||
return size == 0 ? 0xffffffffffffffffULL
|
||||
: (size == 8 ? 0xffffffffffffffffULL
|
||||
: (1ULL << (size * 8)) - 1);
|
||||
}
|
||||
|
||||
static void vec_Value_fini(void *v, void *u) {
|
||||
Value_fini(v);
|
||||
}
|
||||
|
||||
static void RzBinDwarfExprStackItem_fini(RzBinDwarfExprStackItem *self) {
|
||||
static void RzBinDwarfExprStackItem_fini(RzBinDwarfExprStackItem const *self) {
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
@@ -684,8 +671,29 @@ static void RzBinDwarfExprStackItem_fini(RzBinDwarfExprStackItem *self) {
|
||||
RzBinEndianReader_free(self->pc);
|
||||
}
|
||||
|
||||
static void vec_RzBinDwarfExprStackItem_fini(void *v, void *u) {
|
||||
RzBinDwarfExprStackItem_fini(v);
|
||||
static void RzBinDwarfExprStackItem_cpy(RzBinDwarfExprStackItem *dst, RzBinDwarfExprStackItem *src) {
|
||||
rz_return_if_fail(dst && src);
|
||||
memcpy(dst, src, sizeof(RzBinDwarfExprStackItem));
|
||||
dst->pc = RzBinEndianReader_clone(src->pc);
|
||||
dst->bytecode = RzBinEndianReader_clone(src->bytecode);
|
||||
}
|
||||
|
||||
RZ_IPI void RzBinDwarfPiece_fini(RzBinDwarfPiece *x) {
|
||||
if (!x) {
|
||||
return;
|
||||
}
|
||||
rz_bin_dwarf_location_free(x->location);
|
||||
}
|
||||
|
||||
RZ_VECTOR_FINI_T(Value, Value_fini);
|
||||
RZ_VECTOR_FINI_T(RzBinDwarfExprStackItem, RzBinDwarfExprStackItem_fini);
|
||||
RZ_VECTOR_FINI_T(RzBinDwarfPiece, RzBinDwarfPiece_fini);
|
||||
|
||||
RZ_IPI void RzBinDwarfPiece_cpy(RzBinDwarfPiece *dst, RzBinDwarfPiece *src) {
|
||||
rz_return_if_fail(dst && src);
|
||||
memcpy(dst, src, sizeof(RzBinDwarfPiece));
|
||||
dst->location = RZ_NEW0(Location);
|
||||
Location_cpy(dst->location, src->location);
|
||||
}
|
||||
|
||||
RZ_API RZ_OWN RzBinDwarfEvaluation *rz_bin_dwarf_evaluation_new(
|
||||
@@ -697,7 +705,7 @@ RZ_API RZ_OWN RzBinDwarfEvaluation *rz_bin_dwarf_evaluation_new(
|
||||
RzBinDwarfEvaluation *self = RZ_NEW0(RzBinDwarfEvaluation);
|
||||
RET_NULL_IF_FAIL(self);
|
||||
const RzBinDwarfEncoding *encoding = &unit->hdr.encoding;
|
||||
ut64 addr_mask = addrmask_from_size(encoding->address_size);
|
||||
const ut64 addr_mask = addrmask_from_size(encoding->address_size);
|
||||
self->addr_mask = addr_mask;
|
||||
self->bytecode = byte_code;
|
||||
self->encoding = encoding;
|
||||
@@ -705,9 +713,9 @@ RZ_API RZ_OWN RzBinDwarfEvaluation *rz_bin_dwarf_evaluation_new(
|
||||
self->dw = dw;
|
||||
self->unit = unit;
|
||||
self->fn_die = fn_die;
|
||||
rz_vector_init(&self->stack, sizeof(RzBinDwarfValue), vec_Value_fini, NULL);
|
||||
rz_vector_init(&self->expression_stack, sizeof(RzBinDwarfExprStackItem), vec_RzBinDwarfExprStackItem_fini, NULL);
|
||||
rz_vector_init(&self->result, sizeof(RzBinDwarfPiece), (RzVectorFree)RzBinDwarfPiece_fini, NULL);
|
||||
rz_vector_init(&self->stack, sizeof(RzBinDwarfValue), RzVector_Value_fini, NULL);
|
||||
rz_vector_init(&self->expression_stack, sizeof(RzBinDwarfExprStackItem), RzVector_RzBinDwarfExprStackItem_fini, NULL);
|
||||
rz_vector_init(&self->result, sizeof(RzBinDwarfPiece), RzVector_RzBinDwarfPiece_fini, NULL);
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -736,6 +744,19 @@ RZ_API void rz_bin_dwarf_evaluation_free(RZ_OWN RzBinDwarfEvaluation *self) {
|
||||
free(self);
|
||||
}
|
||||
|
||||
RZ_IPI void rz_bin_dwarf_evaluation_cpy(RzBinDwarfEvaluation *dst, RzBinDwarfEvaluation *src) {
|
||||
rz_return_if_fail(dst && src);
|
||||
memcpy(dst, src, sizeof(RzBinDwarfEvaluation));
|
||||
dst->pc = RzBinEndianReader_clone(src->pc);
|
||||
dst->bytecode = RzBinEndianReader_clone(src->bytecode);
|
||||
rz_vector_clone_intof(&dst->stack, &src->stack,
|
||||
(RzVectorItemCpyFunc)Value_cpy);
|
||||
rz_vector_clone_intof(&dst->expression_stack, &src->expression_stack,
|
||||
(RzVectorItemCpyFunc)RzBinDwarfExprStackItem_cpy);
|
||||
rz_vector_clone_intof(&dst->result, &src->result,
|
||||
(RzVectorItemCpyFunc)RzBinDwarfPiece_cpy);
|
||||
}
|
||||
|
||||
RZ_IPI void RzBinDwarfEvaluationResult_fini(RzBinDwarfEvaluationResult *self) {
|
||||
if (self->kind == EvaluationResult_REQUIRES_ENTRY_VALUE) {
|
||||
RzBinDwarfBlock_fini(&self->requires_entry_value.expression);
|
||||
@@ -750,6 +771,15 @@ RZ_API void RzBinDwarfEvaluationResult_free(RZ_OWN RzBinDwarfEvaluationResult *s
|
||||
free(self);
|
||||
}
|
||||
|
||||
RZ_IPI void RzBinDwarfEvaluationResult_cpy(RzBinDwarfEvaluationResult *dst, RzBinDwarfEvaluationResult *src) {
|
||||
rz_return_if_fail(dst && src);
|
||||
memcpy(dst, src, sizeof(RzBinDwarfEvaluationResult));
|
||||
if (src->kind == EvaluationResult_REQUIRES_ENTRY_VALUE) {
|
||||
RzBinDwarfBlock_cpy(&dst->requires_entry_value.expression,
|
||||
&src->requires_entry_value.expression);
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECK_DEFER \
|
||||
do { \
|
||||
if (rz_vector_len(&self->stack) >= 1) { \
|
||||
@@ -851,12 +881,15 @@ static bool Evaluation_evaluate_one_operation(
|
||||
break;
|
||||
}
|
||||
Value *value = rz_vector_index_ptr(&self->stack, len - operation.pick.index - 1);
|
||||
if (!value) {
|
||||
goto err;
|
||||
}
|
||||
Value clone = { 0 };
|
||||
OK_OR_ERR(value &&
|
||||
Value_clone_into(value, &clone) &&
|
||||
Evaluation_push(self, &clone),
|
||||
Value_fini(&clone);
|
||||
goto err);
|
||||
if (!Value_clone_into(value, &clone) &&
|
||||
Evaluation_push(self, &clone)) {
|
||||
Value_fini(&clone);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OPERATION_KIND_SWAP: {
|
||||
@@ -985,10 +1018,13 @@ static bool Evaluation_evaluate_one_operation(
|
||||
ERR_IF_FAIL(v.location);
|
||||
v.location->kind = RzBinDwarfLocationKind_FB_OFFSET;
|
||||
v.location->offset = rz_bin_dwarf_attr_sdata(fb_attr);
|
||||
OK_OR_ERR(Evaluation_push(self, &v),
|
||||
rz_bin_dwarf_location_free(v.location));
|
||||
if (!Evaluation_push(self, &v)) {
|
||||
rz_bin_dwarf_location_free(v.location);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
} else if (fb_attr->value.kind == RzBinDwarfAttr_Block) {
|
||||
}
|
||||
if (fb_attr->value.kind == RzBinDwarfAttr_Block) {
|
||||
RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(rz_bin_dwarf_attr_block(fb_attr), self->dw, self->unit, self->fn_die);
|
||||
if (!loc) {
|
||||
RzBinDWARFDumpOption opt = {
|
||||
@@ -996,8 +1032,9 @@ static bool Evaluation_evaluate_one_operation(
|
||||
.loclist_sep = ",\t",
|
||||
.dwarf_register_mapping = NULL,
|
||||
};
|
||||
const RzBinDwarfEncoding *enc = self->unit ? &self->unit->hdr.encoding : NULL;
|
||||
char *expr_str = rz_bin_dwarf_expression_to_string(
|
||||
&self->unit->hdr.encoding, rz_bin_dwarf_attr_block(fb_attr), &opt);
|
||||
enc, rz_bin_dwarf_attr_block(fb_attr), &opt);
|
||||
RZ_LOG_ERROR("Failed eval frame base: [%s]\n", rz_str_get_null(expr_str));
|
||||
free(expr_str);
|
||||
goto err;
|
||||
@@ -1279,9 +1316,11 @@ RZ_API bool rz_bin_dwarf_evaluation_evaluate(RZ_BORROW RZ_NONNULL RzBinDwarfEval
|
||||
.has_size_in_bits = false,
|
||||
.has_bit_offset = false,
|
||||
};
|
||||
OK_OR_ERR(RzBinDwarfLocation_move(&op_result.complete, piece.location) &&
|
||||
rz_vector_push(&self->result, &piece),
|
||||
rz_bin_dwarf_location_free(location));
|
||||
if (!(RzBinDwarfLocation_move(&op_result.complete, piece.location) &&
|
||||
rz_vector_push(&self->result, &piece))) {
|
||||
rz_bin_dwarf_location_free(location);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
Operation operation = { 0 };
|
||||
ERR_IF_FAIL(Operation_parse(&operation, self->pc, self->encoding));
|
||||
@@ -1297,9 +1336,11 @@ RZ_API bool rz_bin_dwarf_evaluation_evaluate(RZ_BORROW RZ_NONNULL RzBinDwarfEval
|
||||
.bit_offset = operation.piece.bit_offset,
|
||||
};
|
||||
ERR_IF_FAIL(piece.location);
|
||||
OK_OR_ERR(RzBinDwarfLocation_move(&op_result.complete, piece.location) &&
|
||||
rz_vector_push(&self->result, &piece),
|
||||
rz_bin_dwarf_location_free(piece.location));
|
||||
if (!(RzBinDwarfLocation_move(&op_result.complete, piece.location) &&
|
||||
rz_vector_push(&self->result, &piece))) {
|
||||
rz_bin_dwarf_location_free(piece.location);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1317,19 +1358,21 @@ RZ_API bool rz_bin_dwarf_evaluation_evaluate(RZ_BORROW RZ_NONNULL RzBinDwarfEval
|
||||
switch (entry.type) {
|
||||
case RzBinDwarfValueType_LOCATION:
|
||||
status = status && entry.location;
|
||||
AND_DO(status,
|
||||
if (status) {
|
||||
location = entry.location;
|
||||
entry.location = NULL);
|
||||
entry.location = NULL;
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
ut64 addr = 0;
|
||||
AND_DO(status,
|
||||
if (status) {
|
||||
location = RZ_NEW0(RzBinDwarfLocation);
|
||||
status = location &&
|
||||
Value_to_u64(&entry, self->addr_mask, &addr);
|
||||
AND_DO(status,
|
||||
ut64 addr = 0;
|
||||
status = location && Value_to_u64(&entry, self->addr_mask, &addr);
|
||||
if (status) {
|
||||
location->kind = RzBinDwarfLocationKind_ADDRESS;
|
||||
location->address = addr));
|
||||
location->address = addr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1342,9 +1385,10 @@ RZ_API bool rz_bin_dwarf_evaluation_evaluate(RZ_BORROW RZ_NONNULL RzBinDwarfEval
|
||||
};
|
||||
status = rz_vector_push(&self->result, &piece);
|
||||
}
|
||||
OK_OR(status,
|
||||
if (!status) {
|
||||
rz_bin_dwarf_location_free(location);
|
||||
return false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
self->state.kind = EVALUATION_STATE_COMPLETE;
|
||||
@@ -1362,7 +1406,9 @@ RZ_API RZ_BORROW RzVector /*<RzBinDwarfPiece>*/ *rz_bin_dwarf_evaluation_result(
|
||||
|
||||
static bool RzBinDwarfEvaluationResult_to_loc(
|
||||
RzBinDwarfEvaluation *eval, RzBinDwarfEvaluationResult *eval_result, Location *loc) {
|
||||
rz_warn_if_fail(loc);
|
||||
if (!loc) {
|
||||
return false;
|
||||
}
|
||||
if (eval->state.kind != EVALUATION_STATE_COMPLETE || eval_result->kind != EvaluationResult_COMPLETE) {
|
||||
loc->kind = RzBinDwarfLocationKind_EVALUATION_WAITING;
|
||||
loc->eval_waiting.eval = eval;
|
||||
@@ -1376,18 +1422,12 @@ static bool RzBinDwarfEvaluationResult_to_loc(
|
||||
goto beach;
|
||||
}
|
||||
if (rz_vector_len(pieces) == 1) {
|
||||
RzBinDwarfPiece *piece = rz_vector_index_ptr(pieces, 0);
|
||||
result = piece && RzBinDwarfLocation_move(piece->location, loc);
|
||||
goto beach;
|
||||
Location_cpy(loc, ((RzBinDwarfPiece *)rz_vector_index_ptr(pieces, 0))->location);
|
||||
result = true;
|
||||
} else {
|
||||
loc->kind = RzBinDwarfLocationKind_COMPOSITE;
|
||||
loc->composite = rz_vector_clone(pieces);
|
||||
RzBinDwarfPiece *piece = NULL;
|
||||
rz_vector_foreach(pieces, piece) {
|
||||
piece->location = NULL;
|
||||
}
|
||||
loc->composite = rz_vector_clonef(pieces, (RzVectorItemCpyFunc)RzBinDwarfPiece_cpy);
|
||||
result = true;
|
||||
goto beach;
|
||||
}
|
||||
beach:
|
||||
rz_bin_dwarf_evaluation_free(eval);
|
||||
@@ -1415,7 +1455,9 @@ RZ_API RZ_OWN RzBinDwarfLocation *rz_bin_dwarf_location_from_block(
|
||||
|
||||
RzBinDwarfEvaluation *eval = NULL;
|
||||
Location *loc = RZ_NEW0(Location);
|
||||
OK_OR(loc, return NULL);
|
||||
if (!loc) {
|
||||
return NULL;
|
||||
}
|
||||
loc->encoding = unit->hdr.encoding;
|
||||
|
||||
if (rz_bin_dwarf_block_empty(block)) {
|
||||
@@ -1427,8 +1469,10 @@ RZ_API RZ_OWN RzBinDwarfLocation *rz_bin_dwarf_location_from_block(
|
||||
RET_NULL_IF_FAIL(result);
|
||||
eval = rz_bin_dwarf_evaluation_new_from_block(block, dw, unit, die);
|
||||
ERR_IF_FAIL(eval);
|
||||
ERR_IF_FAIL(rz_bin_dwarf_evaluation_evaluate(eval, result) &&
|
||||
RzBinDwarfEvaluationResult_to_loc(eval, result, loc));
|
||||
if (!(rz_bin_dwarf_evaluation_evaluate(eval, result) &&
|
||||
RzBinDwarfEvaluationResult_to_loc(eval, result, loc))) {
|
||||
goto err;
|
||||
};
|
||||
}
|
||||
return loc;
|
||||
err:
|
||||
@@ -1441,7 +1485,7 @@ err:
|
||||
return loc;
|
||||
}
|
||||
|
||||
static void Operation_dump(Operation *op, RzStrBuf *buf) {
|
||||
static void Operation_dump(Operation const *op, RzStrBuf *buf) {
|
||||
rz_strbuf_append(buf, rz_str_get_null(rz_bin_dwarf_op(op->opcode)));
|
||||
switch (op->kind) {
|
||||
case OPERATION_KIND_DROP:
|
||||
@@ -1593,7 +1637,7 @@ RZ_API void rz_bin_dwarf_expression_dump(
|
||||
|
||||
Operation *op = NULL;
|
||||
ut32 i;
|
||||
ut32 end = rz_vector_len(exprs) - 1;
|
||||
const ut32 end = rz_vector_len(exprs) - 1;
|
||||
rz_vector_enumerate(exprs, op, i) {
|
||||
rz_strbuf_append(sb, rz_str_get(opt->expr_indent));
|
||||
Operation_dump(op, sb);
|
||||
@@ -1636,10 +1680,10 @@ RZ_API void rz_bin_dwarf_loclist_dump(
|
||||
}
|
||||
|
||||
ut32 i = 0;
|
||||
ut32 end = rz_pvector_len(&loclist->entries) - 1;
|
||||
const ut32 end = rz_pvector_len(&loclist->entries) - 1;
|
||||
void **it = NULL;
|
||||
rz_pvector_foreach (&loclist->entries, it) {
|
||||
RzBinDwarfLocListEntry *entry = *it;
|
||||
const RzBinDwarfLocListEntry *entry = *it;
|
||||
rz_strbuf_appendf(sb, "%s(0x%" PFMT64x ", %" PFMT64d "):",
|
||||
rz_str_get(opt->loclist_indent), entry->range->begin, entry->range->end - entry->range->begin);
|
||||
|
||||
@@ -1661,7 +1705,7 @@ RZ_API void rz_bin_dwarf_loclist_dump(
|
||||
}
|
||||
|
||||
RZ_API void rz_bin_dwarf_location_composite_dump(
|
||||
RZ_BORROW RZ_NONNULL RzVector /*<RzBinDwarfPiece>*/ *composite,
|
||||
RZ_BORROW RZ_NONNULL const RzVector /*<RzBinDwarfPiece>*/ *composite,
|
||||
RZ_BORROW RZ_NONNULL RzStrBuf *sb,
|
||||
RZ_BORROW RZ_NONNULL const RzBinDWARFDumpOption *opt) {
|
||||
rz_return_if_fail(opt && composite && sb);
|
||||
@@ -1671,13 +1715,17 @@ RZ_API void rz_bin_dwarf_location_composite_dump(
|
||||
}
|
||||
|
||||
ut32 i = 0;
|
||||
ut32 end = rz_vector_len(composite) - 1;
|
||||
const ut32 end = rz_vector_len(composite) - 1;
|
||||
RzBinDwarfPiece *piece = NULL;
|
||||
rz_vector_enumerate(composite, piece, i) {
|
||||
rz_strbuf_append(sb, rz_str_get(opt->composite_indent));
|
||||
rz_strbuf_appendf(sb, "(.%" PFMT64u ", %" PFMT64u "): ", piece->bit_offset, piece->size_in_bits);
|
||||
|
||||
rz_bin_dwarf_location_dump(piece->location, sb, opt);
|
||||
if (piece->location) {
|
||||
rz_bin_dwarf_location_dump(piece->location, sb, opt);
|
||||
} else {
|
||||
rz_strbuf_appendf(sb, "<err:null-location>");
|
||||
}
|
||||
if (i < end) {
|
||||
rz_strbuf_append(sb, rz_str_get(opt->composite_sep));
|
||||
}
|
||||
@@ -1701,15 +1749,25 @@ RZ_API void rz_bin_dwarf_location_dump(
|
||||
rz_strbuf_append(sb, "<decoding error>");
|
||||
break;
|
||||
case RzBinDwarfLocationKind_REGISTER:
|
||||
rz_strbuf_append(sb, opt->dwarf_register_mapping(loc->register_number));
|
||||
if (opt->dwarf_register_mapping) {
|
||||
rz_strbuf_append(sb, opt->dwarf_register_mapping(loc->register_number));
|
||||
} else {
|
||||
rz_strbuf_appendf(sb, "reg%" PFMT64d, loc->register_number);
|
||||
}
|
||||
break;
|
||||
case RzBinDwarfLocationKind_REGISTER_OFFSET:
|
||||
rz_strbuf_appendf(sb, "%s%+" PFMT64d, opt->dwarf_register_mapping(loc->register_number), loc->offset);
|
||||
if (opt->dwarf_register_mapping) {
|
||||
rz_strbuf_append(sb, opt->dwarf_register_mapping(loc->register_number));
|
||||
} else {
|
||||
rz_strbuf_appendf(sb, "reg%" PFMT64d, loc->register_number);
|
||||
}
|
||||
rz_strbuf_appendf(sb, "%+" PFMT64d, loc->offset);
|
||||
break;
|
||||
case RzBinDwarfLocationKind_ADDRESS:
|
||||
rz_strbuf_appendf(sb, "address 0x%" PFMT64x, loc->address);
|
||||
break;
|
||||
case RzBinDwarfLocationKind_VALUE:
|
||||
rz_strbuf_append(sb, "stack");
|
||||
Value_dump(&loc->value, sb, opt);
|
||||
break;
|
||||
case RzBinDwarfLocationKind_BYTES:
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#ifndef RIZIN_OP_H
|
||||
#define RIZIN_OP_H
|
||||
|
||||
#include "loclists.h"
|
||||
|
||||
typedef enum {
|
||||
OPERATION_KIND_DEREF,
|
||||
OPERATION_KIND_DROP,
|
||||
@@ -234,4 +236,8 @@ typedef struct {
|
||||
|
||||
RZ_IPI void RzBinDwarfEvaluationResult_fini(RzBinDwarfEvaluationResult *self);
|
||||
|
||||
RZ_IPI void RzBinDwarfPiece_fini(RzBinDwarfPiece *x);
|
||||
|
||||
RZ_IPI void RzBinDwarfPiece_cpy(RzBinDwarfPiece *dst, RzBinDwarfPiece *src);
|
||||
|
||||
#endif // RIZIN_OP_H
|
||||
|
||||
+12
-10
@@ -1060,40 +1060,42 @@ RZ_IPI void Value_dump(
|
||||
RzStrBuf *sb,
|
||||
const RzBinDWARFDumpOption *opt) {
|
||||
rz_warn_if_fail(self && sb);
|
||||
if (self->type <= 0 || self->type >= RZ_ARRAY_SIZE(Value_strings)) {
|
||||
if (self->type < 0 || self->type >= RZ_ARRAY_SIZE(Value_strings)) {
|
||||
rz_strbuf_append(sb, "<err:invalid value type>");
|
||||
return;
|
||||
}
|
||||
rz_strbuf_append(sb, Value_strings[self->type]);
|
||||
rz_strbuf_append(sb, rz_str_get(opt->loclist_sep));
|
||||
switch (self->type) {
|
||||
case RzBinDwarfValueType_GENERIC:
|
||||
rz_strbuf_appendf(sb, "%" PFMT64x, self->generic);
|
||||
rz_strbuf_appendf(sb, "+%" PFMT64x, self->generic);
|
||||
break;
|
||||
case RzBinDwarfValueType_I8:
|
||||
case RzBinDwarfValueType_I16:
|
||||
case RzBinDwarfValueType_I32:
|
||||
rz_strbuf_appendf(sb, "%" PFMT32d, self->i32);
|
||||
rz_strbuf_appendf(sb, "%+" PFMT32d, self->i32);
|
||||
break;
|
||||
case RzBinDwarfValueType_U8:
|
||||
case RzBinDwarfValueType_U16:
|
||||
case RzBinDwarfValueType_U32:
|
||||
rz_strbuf_appendf(sb, "%" PFMT32u, self->u32);
|
||||
rz_strbuf_appendf(sb, "+%" PFMT32u, self->u32);
|
||||
break;
|
||||
case RzBinDwarfValueType_I64:
|
||||
rz_strbuf_appendf(sb, "%" PFMT64d, self->i64);
|
||||
rz_strbuf_appendf(sb, "%+" PFMT64d, self->i64);
|
||||
break;
|
||||
case RzBinDwarfValueType_U64:
|
||||
rz_strbuf_appendf(sb, "%" PFMT64u, self->u64);
|
||||
rz_strbuf_appendf(sb, "+%" PFMT64u, self->u64);
|
||||
break;
|
||||
case RzBinDwarfValueType_F32:
|
||||
case RzBinDwarfValueType_F64:
|
||||
rz_strbuf_appendf(sb, "%f", self->f64);
|
||||
rz_strbuf_appendf(sb, "%+f", self->f64);
|
||||
break;
|
||||
case RzBinDwarfValueType_LOCATION:
|
||||
rz_bin_dwarf_location_dump(self->location, sb, opt);
|
||||
break;
|
||||
default:
|
||||
rz_strbuf_append(sb, "unimplemented");
|
||||
rz_strbuf_append(sb, "<unimplemented>");
|
||||
break;
|
||||
}
|
||||
if (opt->value_detail) {
|
||||
rz_strbuf_appendf(sb, " : %s", Value_strings[self->type]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-FileCopyrightText: 2023 billow <[email protected]>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef VALUE_H
|
||||
#define VALUE_H
|
||||
|
||||
RZ_IPI bool ValueType_from_encoding(DW_ATE encoding, ut64 byte_size, RzBinDwarfValueType *out_type);
|
||||
RZ_IPI bool ValueType_from_entry(RzBinDwarfDie *entry, RzBinDwarfValueType *out);
|
||||
RZ_IPI bool Value_parse_into(
|
||||
RzBinDwarfValue *value, RzBinDwarfValueType value_type, RzBinEndianReader *reader);
|
||||
RZ_IPI RzBinDwarfValueType Value_type(RzBinDwarfValue *ptr);
|
||||
RZ_IPI bool Value_to_u64(RzBinDwarfValue *self, ut64 addr_mask, ut64 *result);
|
||||
RZ_IPI bool Value_from_u64(RzBinDwarfValueType value_type, ut64 value, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_from_f32(RzBinDwarfValueType value_type, float value, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_from_f64(RzBinDwarfValueType value_type, double value, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_convert(RzBinDwarfValue *self, RzBinDwarfValueType typ, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_reinterpret(RzBinDwarfValue *self, RzBinDwarfValueType value_type, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_abs(RzBinDwarfValue *self, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_neg(RzBinDwarfValue *self, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_add(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_sub(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_mul(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_div(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_rem(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_not(RzBinDwarfValue *self, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_and(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_or(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_xor(RzBinDwarfValue *lhs, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_shift_length(RzBinDwarfValue *self, ut64 *result);
|
||||
RZ_IPI bool Value_shl(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_shr(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_shra(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI bool Value_eq(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_ge(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_gt(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_le(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_lt(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
RZ_IPI bool Value_ne(RzBinDwarfValue *self, RzBinDwarfValue *rhs, ut64 addr_mask, RzBinDwarfValue *result);
|
||||
|
||||
RZ_IPI void Value_fini(RzBinDwarfValue *self);
|
||||
RZ_IPI void Value_free(RzBinDwarfValue *self);
|
||||
RZ_IPI RzBinDwarfValue *Value_clone(RzBinDwarfValue *self);
|
||||
RZ_IPI bool Value_clone_into(RzBinDwarfValue *self, RzBinDwarfValue *val);
|
||||
static inline void Value_cpy(RzBinDwarfValue *dst, RzBinDwarfValue *src) {
|
||||
Value_clone_into(src, dst);
|
||||
}
|
||||
RZ_IPI void Value_dump(
|
||||
const RzBinDwarfValue *self,
|
||||
RzStrBuf *sb,
|
||||
const RzBinDWARFDumpOption *opt);
|
||||
|
||||
#endif // VALUE_H
|
||||
@@ -453,7 +453,7 @@ typedef struct {
|
||||
HtUP /*<ut64, RzCallable *>*/ *callable_by_offset; ///< Store all callables parsed from DWARF by DIE offset
|
||||
HtUP /*<ut64, RzType *>*/ *type_by_offset; ///< Store all RzType parsed from DWARF by DIE offset
|
||||
HtUP /*<ut64, RzBaseType *>*/ *base_type_by_offset; ///< Store all RzBaseType parsed from DWARF by DIE offset
|
||||
HtPP /*<const char*, RzPVector<const RzBaseType *>>*/ *base_type_by_name; ///< Store all RzBaseType parsed from DWARF by DIE offset
|
||||
HtPP /*<const char*, RzPVector<const RzBaseType *>>*/ *base_types_by_name; ///< Store all RzBaseType parsed from DWARF by DIE offset
|
||||
DWARF_RegisterMapping dwarf_register_mapping; ///< Store the mapping function between DWARF registers number and register name in current architecture
|
||||
RzBinDWARF *dw; ///< Holds ownership of RzBinDwarf, avoid releasing it prematurely
|
||||
SetU *visited;
|
||||
|
||||
@@ -1408,7 +1408,7 @@ typedef struct {
|
||||
ut64 offset;
|
||||
bool has_location;
|
||||
RzPVector /*<RzBinDwarfRawLocListEntry *>*/ raw_entries;
|
||||
RzPVector /*<RzBinDwarfLocationListEntry *>*/ entries;
|
||||
RzPVector /*<RzBinDwarfLocListEntry *>*/ entries;
|
||||
} RzBinDwarfLocList;
|
||||
|
||||
typedef struct {
|
||||
@@ -1739,6 +1739,7 @@ typedef struct {
|
||||
const char *composite_sep;
|
||||
const char *composite_indent;
|
||||
const bool compose_breaklines;
|
||||
const bool value_detail;
|
||||
} RzBinDWARFDumpOption;
|
||||
|
||||
RZ_API void rz_bin_dwarf_expression_dump(
|
||||
@@ -1755,7 +1756,7 @@ RZ_API void rz_bin_dwarf_loclist_dump(
|
||||
RZ_BORROW RZ_NONNULL RzStrBuf *sb,
|
||||
RZ_BORROW RZ_NONNULL const RzBinDWARFDumpOption *opt);
|
||||
RZ_API void rz_bin_dwarf_location_composite_dump(
|
||||
RZ_BORROW RZ_NONNULL RzVector /*<RzBinDwarfPiece>*/ *composite,
|
||||
RZ_BORROW RZ_NONNULL const RzVector /*<RzBinDwarfPiece>*/ *composite,
|
||||
RZ_BORROW RZ_NONNULL RzStrBuf *sb,
|
||||
RZ_BORROW RZ_NONNULL const RzBinDWARFDumpOption *opt);
|
||||
RZ_API void rz_bin_dwarf_location_dump(
|
||||
@@ -1819,7 +1820,7 @@ RZ_API RZ_OWN RzBinDwarfAddr *rz_bin_dwarf_addr_from_file(RZ_BORROW RZ_NONNULL R
|
||||
*/
|
||||
static inline char *rz_bin_dwarf_attr_string(
|
||||
const RzBinDwarfAttr *attr,
|
||||
RzBinDWARF *dw,
|
||||
const RzBinDWARF *dw,
|
||||
ut64 str_offsets_base) {
|
||||
rz_return_val_if_fail(attr, NULL);
|
||||
const RzBinDwarfAttrValue *v = &attr->value;
|
||||
@@ -1837,7 +1838,7 @@ static inline char *rz_bin_dwarf_attr_string(
|
||||
|
||||
static inline ut64 rz_bin_dwarf_attr_addr(
|
||||
const RzBinDwarfAttr *attr,
|
||||
RzBinDWARF *dw,
|
||||
const RzBinDWARF *dw,
|
||||
ut64 addr_size, ut64 base) {
|
||||
rz_return_val_if_fail(attr, UT64_MAX);
|
||||
|
||||
|
||||
@@ -238,6 +238,25 @@ static bool test_dwarf_function_parsing_rust(void) {
|
||||
check_fn(0x5270, "bubble_sort<i32>", "void bubble_sort<i32>(struct &mut [i32] values)");
|
||||
check_fn(0x8730, "lang_start_internal", "isize lang_start_internal(struct &Fn<()> main, isize argc, u8 **argv)");
|
||||
|
||||
RzBinDwarfCompUnit *cu = ht_up_find(dw->info->unit_by_offset, 0x4151, NULL);
|
||||
mu_assert_notnull(cu, "Couldn't get compunit");
|
||||
RzBinDwarfLocList *loclist = rz_bin_dwarf_loclists_get(dw->loclists, dw->addr, cu, 0xd973);
|
||||
mu_assert_notnull(loclist, "Couldn't get loclist");
|
||||
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 0);
|
||||
mu_assert_notnull(entry, "Couldn't get entry");
|
||||
mu_assert_notnull(entry->range, "Couldn't get entry range");
|
||||
mu_assert_notnull(entry->expression, "Couldn't get entry expression");
|
||||
mu_assert_eq(entry->range->begin, 0x84e1, "Err entry begin");
|
||||
mu_assert_eq(entry->range->end, 0x84fc, "Err entry end");
|
||||
RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(entry->expression, dw, cu, NULL);
|
||||
mu_assert_notnull(loc, "Couldn't get location");
|
||||
RzBinDWARFDumpOption dump_option = {
|
||||
.composite_sep = ", "
|
||||
};
|
||||
char *locstr = rz_bin_dwarf_location_to_string(loc, &dump_option);
|
||||
mu_assert_streq_free(locstr, "composite: [(.0, 64): stack+18, (.0, 64): stack+8]", "Error location string");
|
||||
rz_bin_dwarf_location_free(loc);
|
||||
|
||||
rz_bin_dwarf_free(dw);
|
||||
rz_core_free(core);
|
||||
mu_end;
|
||||
|
||||
Reference in New Issue
Block a user