mirror of
https://github.com/radareorg/r2flutter.git
synced 2026-11-07 06:26:00 -10:00
Add modern_collect_direct_pool_refs batch pool resolver
Single-pass counterpart of the per-slot -O decode: walk every direct (tagged, snapshotable) ObjectPool entry once and report its resolved kind/name/cid/code_index via modern_resolve_pool_entry, the same resolver -O uses. Non-object entries (native stubs, reset/bootstrap behaviors) are labeled by kind; only plain immediates are skipped. Lets a caller resolve tens of thousands of PP slots without building a value graph per slot.
This commit is contained in:
1 parent
2396599251
commit
f35d5b569d
2 files changed
+95
-1
No files matched your search
@@ -999,7 +999,7 @@ static ModernFillSpec modern_get_fill_spec(const ModernCidCache *cids, int cid)
|
||||
if (modern_cid_eq (cid, cids->patch_class)) {
|
||||
// FullAOT PatchClass layout differs across snapshot families. Before
|
||||
// Dart 3.0 UntaggedPatchClass serialised patched_class, origin_class and
|
||||
// script -- three refs up to to_snapshot(). Dart 3.0 dropped origin_class
|
||||
// script -- three refs up to to_snapshot (). Dart 3.0 dropped origin_class
|
||||
// (and renamed patched_class to wrapped_class), leaving wrapped_class and
|
||||
// script: two refs. The CID_SHIFT1 tag style spans that change (Dart
|
||||
// 2.14-3.3), so the count has to key off the Dart version rather than the
|
||||
@@ -3995,6 +3995,84 @@ bool modern_extract_pool_strings(const ModernReq *req, RList *strings, HtUP *see
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Walk every direct (tagged, snapshotable) ObjectPool entry once and hand the
|
||||
// caller its resolved kind/name/code_index. This is the single-pass batch
|
||||
// counterpart of the per-slot `-O` decode, used by the analysis so PP-slot
|
||||
// comments can show what a slot actually holds instead of a bare offset.
|
||||
bool modern_collect_direct_pool_refs(const ModernReq *req, ModernPoolRefCb cb, void *user) {
|
||||
DartCtx *ctx = req? req->ctx: NULL;
|
||||
if (!ctx || !cb || !modern_supported (ctx)) {
|
||||
return false;
|
||||
}
|
||||
ModernClusterMeta *meta = modern_parse_cluster_meta (ctx, req->cluster_start, req->cluster_end, req->num_clusters, req->num_base_objects);
|
||||
if (!meta) {
|
||||
return false;
|
||||
}
|
||||
ModernRefResolver resolver = { 0 };
|
||||
bool ok = modern_ref_resolver_init (&resolver, ctx, meta, req->num_clusters, req->num_base_objects);
|
||||
if (!ok) {
|
||||
modern_cluster_meta_free (meta, req->num_clusters);
|
||||
return false;
|
||||
}
|
||||
const ModernCidCache cids = modern_cid_cache_init (ctx->layout);
|
||||
for (ut64 i = 0; i < req->num_clusters && ok; i++) {
|
||||
ModernClusterMeta *m = &meta[i];
|
||||
if (m->fill_kind != MODERN_FILL_OBJECT_POOL || !m->fill_parsed || !m->fill_ok || m->fill_offset >= m->fill_end || !m->count) {
|
||||
continue;
|
||||
}
|
||||
ClusterStream s = {
|
||||
.ctx = ctx,
|
||||
.cursor = m->fill_offset,
|
||||
.end = m->fill_end,
|
||||
};
|
||||
for (ut64 pool_index = 0; pool_index < m->count && ok; pool_index++) {
|
||||
ut64 length = 0;
|
||||
if (!cs_read_unsigned (&s, &length)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
for (ut64 entry_index = 0; entry_index < length; entry_index++) {
|
||||
ModernPoolEntry entry;
|
||||
if (!modern_read_pool_entry (&s, ctx, entry_index, &entry)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
// Skip only plain immediates (raw Smi constants already shown in
|
||||
// the disassembly). Everything else - tagged objects, native
|
||||
// function stubs and reset/bootstrap behaviors - gets labeled by
|
||||
// its kind so no slot is left as a bare offset.
|
||||
if (entry.behavior == 0 && entry.type == 0) {
|
||||
continue;
|
||||
}
|
||||
ModernResolvedRef resolved;
|
||||
modern_resolve_pool_entry (&resolver, &cids, entry.type, entry.behavior, entry.ref, &resolved);
|
||||
if (R_STR_ISEMPTY (resolved.kind)) {
|
||||
modern_resolved_ref_fini (&resolved);
|
||||
continue;
|
||||
}
|
||||
ut64 value_addr = entry.ref < resolver.refs_count? resolver.string_addr_by_ref[entry.ref]: 0;
|
||||
ModernPoolRefInfo info = {
|
||||
.pp_offset = modern_pool_entry_pp_offset (ctx, entry_index),
|
||||
.pool_ref = m->start_ref + pool_index,
|
||||
.pool_index = pool_index,
|
||||
.entry_index = entry_index,
|
||||
.ref = entry.ref,
|
||||
.kind = resolved.kind,
|
||||
.name = resolved.name,
|
||||
.cid = resolved.cid,
|
||||
.code_index = resolved.code_index,
|
||||
.value_addr = value_addr,
|
||||
};
|
||||
cb (&info, user);
|
||||
modern_resolved_ref_fini (&resolved);
|
||||
}
|
||||
}
|
||||
}
|
||||
modern_ref_resolver_fini (&resolver);
|
||||
modern_cluster_meta_free (meta, req->num_clusters);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool modern_emit_summary(const ModernSummaryReq *req) {
|
||||
if (!req || !req->ctx) {
|
||||
return false;
|
||||
|
||||
@@ -182,6 +182,21 @@ typedef struct {
|
||||
|
||||
typedef void(*ModernPoolStrRefCb)(const ModernPoolStrRef *info, void *user);
|
||||
|
||||
typedef struct {
|
||||
ut64 pp_offset;
|
||||
ut64 pool_ref;
|
||||
ut64 pool_index;
|
||||
ut64 entry_index;
|
||||
ut64 ref;
|
||||
const char *kind; // resolved kind: "string", "function", "class", "code", ...
|
||||
const char *name; // resolved name/value, or NULL (valid only during the callback)
|
||||
int cid;
|
||||
ut64 code_index; // UT64_MAX when the entry does not resolve to code
|
||||
ut64 value_addr; // snapshot address of the resolved object, or 0
|
||||
} ModernPoolRefInfo;
|
||||
|
||||
typedef void(*ModernPoolRefCb)(const ModernPoolRefInfo *info, void *user);
|
||||
|
||||
typedef void(*DartInstructionTableEntryCallback)(const DartInstructionTableEntry *entry, void *user);
|
||||
|
||||
typedef struct {
|
||||
@@ -274,6 +289,7 @@ void modern_value_graph_json(PJ *pj, ModernValueGraph *graph);
|
||||
void modern_value_graph_text(RStrBuf *sb, ModernValueGraph *graph);
|
||||
const char *modern_value_graph_root_kind(ModernValueGraph *graph);
|
||||
bool modern_collect_direct_pool_strrefs(const ModernReq *req, HtUP *pp_offs, ModernPoolStrRefCb cb, void *user);
|
||||
bool modern_collect_direct_pool_refs(const ModernReq *req, ModernPoolRefCb cb, void *user);
|
||||
bool modern_collect_pool_strrefs(const ModernReq *req, HtUP *pp_offs, ModernPoolStrRefCb cb, void *user);
|
||||
bool modern_extract_pool_strings(const ModernReq *req, RList *strings, HtUP *seen, ut64 *next_ref);
|
||||
bool modern_scan_names(DartCtx *ctx, ut64 start, ut64 end, ut64 nclusters, ut64 itlen);
|
||||
|
||||
Reference in new issue
Block a user