mirror of
https://github.com/radareorg/r2flutter.git
synced 2026-11-07 06:26:00 -10:00
Support Dart 3.13 Single Snapshots
This commit is contained in:
1 parent
2e85b70bda
commit
3fe9dff0cc
12 files changed
+296
-76
No files matched your search
+2
-1
@@ -21,9 +21,10 @@ cluster layouts next, then metadata/value restoration and profile detection.
|
||||
- [x] **R2F-DAE-004 — Parse versioned Code cluster layouts**
|
||||
- Profile Code reference counts, text-offset deltas, and leading refs.
|
||||
- Commit: `Parse Versioned Code Cluster Layouts`
|
||||
- [ ] **R2F-DAE-005 — Support Dart 3.13 single snapshots**
|
||||
- [x] **R2F-DAE-005 — Support Dart 3.13 single snapshots**
|
||||
- Add hashes/CIDs and merged VM/isolate snapshot handling.
|
||||
- Add the alternate symbols and 3.13 Class, Code, and Closure layouts.
|
||||
- Test complete and truncated combined snapshots, including partial-fill failure reporting.
|
||||
- Commit: `Support Dart 3.13 Single Snapshots`
|
||||
- [ ] **R2F-DAE-006 — Retain serialized class layout metadata**
|
||||
- Keep class ID, library/super references, next-field offset, and bitmap.
|
||||
|
||||
@@ -1425,3 +1425,31 @@ profile is applied while framing the Code stream and while recovering Code
|
||||
owners; DAE's Dart 2.18 negative fill adjustment is intentionally not copied,
|
||||
because it compensates for drift in DAE's own generic fill walker rather than
|
||||
a serialized SDK field.
|
||||
|
||||
## Dart 3.13 Uses One Combined Snapshot
|
||||
|
||||
Dart 3.13 replaces the separate VM and isolate AOT snapshots with one full
|
||||
snapshot (`kind=2`). Its exported symbols are `_kDartSnapshotData` and
|
||||
`_kDartSnapshotText`. r2flutter stores those addresses in its existing isolate
|
||||
slots internally so the parser APIs remain compatible, but reports a single
|
||||
`Combined` snapshot and does not invent VM addresses in user-facing output.
|
||||
Unknown hashes remain on the newest split-snapshot compatibility profile;
|
||||
otherwise merely adding a 3.13 profile would silently reinterpret older dev
|
||||
builds as combined snapshots. Exact hashes and explicit overrides are positive
|
||||
evidence for the new topology, while structural selection is handled
|
||||
separately.
|
||||
|
||||
The same release changes three cluster details independently: Class allocation
|
||||
becomes a single fixed-size count, Code fill gains two leading references, and
|
||||
Closure becomes variable-sized with an allocation length followed during fill
|
||||
by one unsigned value, three fixed references, and that many variable
|
||||
references. The Class nullable-field bitmap is omitted only for synthetic
|
||||
top-level class IDs. That offset is itself versioned: `1 << 16` through Dart
|
||||
2.18 and `1 << 20` from Dart 2.19 onward. Applying the newer threshold to a
|
||||
2.18 snapshot, or the older threshold to 3.13, shifts subsequent fills for
|
||||
ordinary high class IDs.
|
||||
|
||||
Keep partial cluster summaries when a fill is truncated. Earlier clusters are
|
||||
still useful, while the failing cluster is marked `failed` and later clusters
|
||||
remain `not_parsed`. This is more informative than rejecting the whole snapshot
|
||||
and makes malformed-input behavior explicit to JSON consumers.
|
||||
@@ -12,6 +12,7 @@ typedef struct {
|
||||
} DartHashEntry;
|
||||
|
||||
static const DartHashEntry dart_hash_entries[] = {
|
||||
{ "0451907c2eaa8467e848c0067bfe8ed4", 4 }, // Dart 3.13.0
|
||||
{ "0c7f1aa25fc597a7b3b9a19ed390afa1", 8 }, // Dart 2.13.0
|
||||
{ "0eb277b50d6ce4069261c69150ce52c9", 4 }, // Dart 2.17.0
|
||||
{ "1441d6b13b8623fa7fbf61433abebd31", 4 }, // Dart 2.17.6
|
||||
@@ -36,6 +37,7 @@ static const DartHashEntry dart_hash_entries[] = {
|
||||
{ "77b867742ae1ace67fbbb9a9a0d0334e", 4 }, // Dart 3.3.0
|
||||
{ "77bd0a83c49bfc555a44a0740f15003a", 4 }, // Dart 2.18.0
|
||||
{ "78da37fed6bf1489361a312568249f3f", 4 }, // Dart 3.11.5
|
||||
{ "7a1ea3f6f5cf1089a7f6e55d7f20dbfd", 4 }, // Dart 3.14.0
|
||||
{ "7a5b240780941844bae88eca5dbaa7b8", 8 }, // Dart 2.13.0
|
||||
{ "7b96ef6dda75bdd1d70be8c2f7cb814e", 8 }, // Dart 2.15.0
|
||||
{ "7dbbeeb8ef7b91338640dca3927636de", 4 }, // Dart 3.1.3
|
||||
@@ -76,7 +78,7 @@ static const DartHashEntry dart_hash_entries[] = {
|
||||
{ "fe53c4fdba846005b70514aec3840296", 8 }, // Dart 3.4.0
|
||||
};
|
||||
|
||||
#define DART_HASH_ENTRIES_COUNT 62
|
||||
#define DART_HASH_ENTRIES_COUNT 64
|
||||
|
||||
// Default offset arrays (identical across all known Dart versions)
|
||||
#define DART_DEFAULT_EP_OFFSETS \
|
||||
|
||||
@@ -77,6 +77,10 @@ typedef struct {
|
||||
int code_refs;
|
||||
int code_leading_refs;
|
||||
bool code_has_text_offset;
|
||||
bool single_snapshot;
|
||||
bool class_alloc_fixed;
|
||||
bool closure_variable;
|
||||
bool class_top_level_cid20;
|
||||
} DartVerLayout;
|
||||
|
||||
// Lookup Dart version from a snapshot hash (MD5)
|
||||
@@ -87,15 +91,18 @@ const char *dart_version_from_hash(const char *hash);
|
||||
// Returns NULL if the version string is not a dotted numeric version.
|
||||
const DartVerLayout *dart_profile_from_version(const char *version);
|
||||
|
||||
// Pick a layout structure based on hash, with fallback to defaults
|
||||
// Pick a layout structure based on hash, with fallback to a compatible baseline
|
||||
// Returns a newly allocated DartVerLayout (caller must free)
|
||||
// If hash is unknown, fingerprints against the newest known layout profile
|
||||
// If hash is unknown, fingerprints against the newest split-snapshot profile.
|
||||
DartVerLayout *dart_layout_from_hash(const char *hash);
|
||||
|
||||
// Newest known layout profile (used as the fingerprint baseline for unknown
|
||||
// git/dev builds, whose snapshot format tracks the latest release).
|
||||
// Newest known layout profile.
|
||||
const DartVerLayout *dart_newest_profile(void);
|
||||
|
||||
// Conservative profile used until an unknown hash can be structurally probed.
|
||||
// Single-snapshot mechanics require positive evidence and are not inherited.
|
||||
const DartVerLayout *dart_fingerprint_profile(void);
|
||||
|
||||
// Human-readable name for a DartVersionSource value.
|
||||
const char *dart_version_source_str(int source);
|
||||
|
||||
|
||||
+6
-2
@@ -28,7 +28,9 @@
|
||||
"3.9.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 112, "typed_data_internal_limit": 168, "typed_data_stride": 4, "cids": {"ILLEGAL": 0, "NATIVE_POINTER": 1, "CLASS": 5, "PATCH_CLASS": 6, "FUNCTION": 7, "TYPE_PARAMETERS": 8, "CLOSURE_DATA": 9, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 16, "WEAK_ARRAY": 17, "CODE": 18, "OBJECT_POOL": 23, "PC_DESCRIPTORS": 24, "CODE_SOURCE_MAP": 25, "COMPRESSED_STACK_MAPS": 26, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 35, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "INSTANCE": 45, "LIBRARY_PREFIX": 46, "TYPE_ARGUMENTS": 47, "TYPE": 49, "FUNCTION_TYPE": 50, "RECORD_TYPE": 51, "TYPE_PARAMETER": 52, "CLOSURE": 57, "MINT": 61, "DOUBLE": 62, "FLOAT32X4": 64, "INT32X4": 65, "FLOAT64X2": 66, "RECORD": 67, "TYPED_DATA": 69, "EXTERNAL_TYPED_DATA": 70, "TYPED_DATA_VIEW": 71, "CAPABILITY": 74, "RECEIVE_PORT": 75, "SEND_PORT": 76, "STACK_TRACE": 77, "SUSPEND_STATE": 78, "REGEXP": 79, "WEAK_PROPERTY": 80, "WEAK_REFERENCE": 81, "FUTURE_OR": 83, "USER_TAG": 84, "TRANSFERABLE_TYPED_DATA": 85, "MAP": 86, "CONST_MAP": 87, "SET": 88, "CONST_SET": 89, "ARRAY": 90, "IMMUTABLE_ARRAY": 91, "GROWABLE_OBJECT_ARRAY": 92, "STRING": 93, "ONE_BYTE_STRING": 94, "TWO_BYTE_STRING": 95, "NUM_PREDEFINED_CIDS": 175}},
|
||||
"3.10.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 112, "typed_data_internal_limit": 168, "typed_data_stride": 4, "cids": {"ILLEGAL": 0, "NATIVE_POINTER": 1, "CLASS": 5, "PATCH_CLASS": 6, "FUNCTION": 7, "TYPE_PARAMETERS": 8, "CLOSURE_DATA": 9, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 16, "WEAK_ARRAY": 17, "CODE": 18, "OBJECT_POOL": 23, "PC_DESCRIPTORS": 24, "CODE_SOURCE_MAP": 25, "COMPRESSED_STACK_MAPS": 26, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 35, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "INSTANCE": 45, "LIBRARY_PREFIX": 46, "TYPE_ARGUMENTS": 47, "TYPE": 49, "FUNCTION_TYPE": 50, "RECORD_TYPE": 51, "TYPE_PARAMETER": 52, "CLOSURE": 57, "MINT": 61, "DOUBLE": 62, "FLOAT32X4": 64, "INT32X4": 65, "FLOAT64X2": 66, "RECORD": 67, "TYPED_DATA": 69, "EXTERNAL_TYPED_DATA": 70, "TYPED_DATA_VIEW": 71, "CAPABILITY": 74, "RECEIVE_PORT": 75, "SEND_PORT": 76, "STACK_TRACE": 77, "SUSPEND_STATE": 78, "REGEXP": 79, "WEAK_PROPERTY": 80, "WEAK_REFERENCE": 81, "FUTURE_OR": 83, "USER_TAG": 84, "TRANSFERABLE_TYPED_DATA": 85, "MAP": 86, "CONST_MAP": 87, "SET": 88, "CONST_SET": 89, "ARRAY": 90, "IMMUTABLE_ARRAY": 91, "GROWABLE_OBJECT_ARRAY": 92, "STRING": 93, "ONE_BYTE_STRING": 94, "TWO_BYTE_STRING": 95, "NUM_PREDEFINED_CIDS": 175}},
|
||||
"3.11.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 112, "typed_data_internal_limit": 168, "typed_data_stride": 4, "cids": {"ILLEGAL": 0, "NATIVE_POINTER": 1, "CLASS": 5, "PATCH_CLASS": 6, "FUNCTION": 7, "TYPE_PARAMETERS": 8, "CLOSURE_DATA": 9, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 16, "WEAK_ARRAY": 17, "CODE": 18, "OBJECT_POOL": 23, "PC_DESCRIPTORS": 24, "CODE_SOURCE_MAP": 25, "COMPRESSED_STACK_MAPS": 26, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 35, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "INSTANCE": 45, "LIBRARY_PREFIX": 46, "TYPE_ARGUMENTS": 47, "TYPE": 49, "FUNCTION_TYPE": 50, "RECORD_TYPE": 51, "TYPE_PARAMETER": 52, "CLOSURE": 57, "MINT": 61, "DOUBLE": 62, "FLOAT32X4": 64, "INT32X4": 65, "FLOAT64X2": 66, "RECORD": 67, "TYPED_DATA": 69, "EXTERNAL_TYPED_DATA": 70, "TYPED_DATA_VIEW": 71, "CAPABILITY": 74, "RECEIVE_PORT": 75, "SEND_PORT": 76, "STACK_TRACE": 77, "SUSPEND_STATE": 78, "REGEXP": 79, "WEAK_PROPERTY": 80, "WEAK_REFERENCE": 81, "FUTURE_OR": 83, "USER_TAG": 84, "TRANSFERABLE_TYPED_DATA": 85, "MAP": 86, "CONST_MAP": 87, "SET": 88, "CONST_SET": 89, "ARRAY": 90, "IMMUTABLE_ARRAY": 91, "GROWABLE_OBJECT_ARRAY": 92, "STRING": 93, "ONE_BYTE_STRING": 94, "TWO_BYTE_STRING": 95, "NUM_PREDEFINED_CIDS": 175}},
|
||||
"3.12.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 112, "typed_data_internal_limit": 168, "typed_data_stride": 4, "cids": {"ILLEGAL": 0, "NATIVE_POINTER": 1, "CLASS": 5, "PATCH_CLASS": 6, "FUNCTION": 7, "TYPE_PARAMETERS": 8, "CLOSURE_DATA": 9, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 16, "WEAK_ARRAY": 17, "CODE": 18, "OBJECT_POOL": 23, "PC_DESCRIPTORS": 24, "CODE_SOURCE_MAP": 25, "COMPRESSED_STACK_MAPS": 26, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 35, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "INSTANCE": 45, "LIBRARY_PREFIX": 46, "TYPE_ARGUMENTS": 47, "TYPE": 49, "FUNCTION_TYPE": 50, "RECORD_TYPE": 51, "TYPE_PARAMETER": 52, "CLOSURE": 57, "MINT": 61, "DOUBLE": 62, "FLOAT32X4": 64, "INT32X4": 65, "FLOAT64X2": 66, "RECORD": 67, "TYPED_DATA": 69, "EXTERNAL_TYPED_DATA": 70, "TYPED_DATA_VIEW": 71, "CAPABILITY": 74, "RECEIVE_PORT": 75, "SEND_PORT": 76, "STACK_TRACE": 77, "SUSPEND_STATE": 78, "REGEXP": 79, "WEAK_PROPERTY": 80, "WEAK_REFERENCE": 81, "FUTURE_OR": 83, "USER_TAG": 84, "TRANSFERABLE_TYPED_DATA": 85, "MAP": 86, "CONST_MAP": 87, "SET": 88, "CONST_SET": 89, "ARRAY": 90, "IMMUTABLE_ARRAY": 91, "GROWABLE_OBJECT_ARRAY": 92, "STRING": 93, "ONE_BYTE_STRING": 94, "TWO_BYTE_STRING": 95, "NUM_PREDEFINED_CIDS": 175}}
|
||||
"3.12.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 112, "typed_data_internal_limit": 168, "typed_data_stride": 4, "cids": {"ILLEGAL": 0, "NATIVE_POINTER": 1, "CLASS": 5, "PATCH_CLASS": 6, "FUNCTION": 7, "TYPE_PARAMETERS": 8, "CLOSURE_DATA": 9, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 16, "WEAK_ARRAY": 17, "CODE": 18, "OBJECT_POOL": 23, "PC_DESCRIPTORS": 24, "CODE_SOURCE_MAP": 25, "COMPRESSED_STACK_MAPS": 26, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 35, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "INSTANCE": 45, "LIBRARY_PREFIX": 46, "TYPE_ARGUMENTS": 47, "TYPE": 49, "FUNCTION_TYPE": 50, "RECORD_TYPE": 51, "TYPE_PARAMETER": 52, "CLOSURE": 57, "MINT": 61, "DOUBLE": 62, "FLOAT32X4": 64, "INT32X4": 65, "FLOAT64X2": 66, "RECORD": 67, "TYPED_DATA": 69, "EXTERNAL_TYPED_DATA": 70, "TYPED_DATA_VIEW": 71, "CAPABILITY": 74, "RECEIVE_PORT": 75, "SEND_PORT": 76, "STACK_TRACE": 77, "SUSPEND_STATE": 78, "REGEXP": 79, "WEAK_PROPERTY": 80, "WEAK_REFERENCE": 81, "FUTURE_OR": 83, "USER_TAG": 84, "TRANSFERABLE_TYPED_DATA": 85, "MAP": 86, "CONST_MAP": 87, "SET": 88, "CONST_SET": 89, "ARRAY": 90, "IMMUTABLE_ARRAY": 91, "GROWABLE_OBJECT_ARRAY": 92, "STRING": 93, "ONE_BYTE_STRING": 94, "TWO_BYTE_STRING": 95, "NUM_PREDEFINED_CIDS": 175}},
|
||||
"3.13.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 113, "typed_data_internal_limit": 169, "typed_data_stride": 4, "cids": {"ILLEGAL": 0, "NATIVE_POINTER": 1, "CLASS": 5, "PATCH_CLASS": 6, "FUNCTION": 7, "TYPE_PARAMETERS": 8, "CLOSURE_DATA": 9, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 16, "WEAK_ARRAY": 17, "CODE": 18, "OBJECT_POOL": 23, "PC_DESCRIPTORS": 24, "CODE_SOURCE_MAP": 25, "COMPRESSED_STACK_MAPS": 26, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 35, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "INSTANCE": 45, "LIBRARY_PREFIX": 46, "TYPE_ARGUMENTS": 47, "TYPE": 49, "FUNCTION_TYPE": 50, "RECORD_TYPE": 51, "TYPE_PARAMETER": 52, "CLOSURE": 57, "MINT": 61, "DOUBLE": 62, "FLOAT32X4": 64, "INT32X4": 65, "FLOAT64X2": 66, "RECORD": 67, "TYPED_DATA": 69, "EXTERNAL_TYPED_DATA": 70, "TYPED_DATA_VIEW": 71, "CAPABILITY": 74, "RECEIVE_PORT": 75, "SEND_PORT": 76, "STACK_TRACE": 77, "SUSPEND_STATE": 78, "REGEXP": 79, "WEAK_PROPERTY": 80, "WEAK_REFERENCE": 81, "FUTURE_OR": 83, "USER_TAG": 84, "TRANSFERABLE_TYPED_DATA": 85, "MAP": 86, "CONST_MAP": 87, "SET": 88, "CONST_SET": 89, "ARRAY": 90, "IMMUTABLE_ARRAY": 91, "GROWABLE_OBJECT_ARRAY": 92, "STRING": 93, "ONE_BYTE_STRING": 94, "TWO_BYTE_STRING": 95, "NUM_PREDEFINED_CIDS": 176}},
|
||||
"3.14.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 113, "typed_data_internal_limit": 169, "typed_data_stride": 4, "cids": {"ILLEGAL": 0, "NATIVE_POINTER": 1, "CLASS": 5, "PATCH_CLASS": 6, "FUNCTION": 7, "TYPE_PARAMETERS": 8, "CLOSURE_DATA": 9, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 16, "WEAK_ARRAY": 17, "CODE": 18, "OBJECT_POOL": 23, "PC_DESCRIPTORS": 24, "CODE_SOURCE_MAP": 25, "COMPRESSED_STACK_MAPS": 26, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 35, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "INSTANCE": 45, "LIBRARY_PREFIX": 46, "TYPE_ARGUMENTS": 47, "TYPE": 49, "FUNCTION_TYPE": 50, "RECORD_TYPE": 51, "TYPE_PARAMETER": 52, "CLOSURE": 57, "MINT": 61, "DOUBLE": 62, "FLOAT32X4": 64, "INT32X4": 65, "FLOAT64X2": 66, "RECORD": 67, "TYPED_DATA": 69, "EXTERNAL_TYPED_DATA": 70, "TYPED_DATA_VIEW": 71, "CAPABILITY": 74, "RECEIVE_PORT": 75, "SEND_PORT": 76, "STACK_TRACE": 77, "SUSPEND_STATE": 78, "REGEXP": 79, "WEAK_PROPERTY": 80, "WEAK_REFERENCE": 81, "FUTURE_OR": 83, "USER_TAG": 84, "TRANSFERABLE_TYPED_DATA": 85, "MAP": 86, "CONST_MAP": 87, "SET": 88, "CONST_SET": 89, "ARRAY": 90, "IMMUTABLE_ARRAY": 91, "GROWABLE_OBJECT_ARRAY": 92, "STRING": 93, "ONE_BYTE_STRING": 94, "TWO_BYTE_STRING": 95, "NUM_PREDEFINED_CIDS": 176}}
|
||||
},
|
||||
"hashes": {
|
||||
"8ee4ef7a67df9845fba331734198a953": "2.10.0",
|
||||
@@ -92,6 +94,8 @@
|
||||
"1ce86630892e2dca9a8543fdb8ed8e22": "3.10.7",
|
||||
"78da37fed6bf1489361a312568249f3f": "3.11.5",
|
||||
"41be3daaabd524b8aa7423bc24584957": "3.12.0",
|
||||
"ace654289f5abc240509fc941453ebc5": "3.12.1"
|
||||
"ace654289f5abc240509fc941453ebc5": "3.12.1",
|
||||
"0451907c2eaa8467e848c0067bfe8ed4": "3.13.0",
|
||||
"7a1ea3f6f5cf1089a7f6e55d7f20dbfd": "3.14.0"
|
||||
}
|
||||
}
|
||||
@@ -635,6 +635,17 @@ def code_layout_for_version(version):
|
||||
}
|
||||
|
||||
|
||||
def snapshot_layout_for_version(version):
|
||||
parsed = parse_version(version)
|
||||
modern_single = parsed >= (3, 13)
|
||||
return {
|
||||
"single": "true" if modern_single else "false",
|
||||
"class_fixed": "true" if modern_single else "false",
|
||||
"closure_variable": "true" if modern_single else "false",
|
||||
"class_top_level_cid20": "true" if parsed >= (2, 19) else "false",
|
||||
}
|
||||
|
||||
|
||||
def profile_diff(existing, inferred):
|
||||
diffs = []
|
||||
for key in ("cws", "heap_object_tag", "max_alignment", "it_cap", "tag_style", "header_fields"):
|
||||
@@ -752,11 +763,14 @@ def gen_profile_entries(offsets):
|
||||
ref_encoding = ref_encoding_for_version(ver)
|
||||
pool_encoding = pool_encoding_for_version(ver)
|
||||
code = code_layout_for_version(ver)
|
||||
snapshot = snapshot_layout_for_version(ver)
|
||||
lines.append(f'\t{{ "", "{ver}", {v["cws"]}, {v["heap_object_tag"]}, '
|
||||
f'{v["max_alignment"]}, {v["it_cap"]}, {tag_name}, '
|
||||
f'{v["header_fields"]}, {header_style}, {ref_encoding}, {pool_encoding}, '
|
||||
f'{code["alloc"]}, {code["refs"]}, {code["leading_refs"]}, {code["has_text_offset"]} }}, // Dart {ver}')
|
||||
lines.append("\t{ { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }")
|
||||
f'{code["alloc"]}, {code["refs"]}, {code["leading_refs"]}, {code["has_text_offset"]}, '
|
||||
f'{snapshot["single"]}, {snapshot["class_fixed"]}, {snapshot["closure_variable"]}, '
|
||||
f'{snapshot["class_top_level_cid20"]} }}, // Dart {ver}')
|
||||
lines.append("\t{ { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }")
|
||||
lines.append("};")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ static const DartCidTable cid_tables[] = {
|
||||
{ "3.10.0", { CID (ILLEGAL, 0), CID (NATIVE_POINTER, 1), CID (CLASS, 5), CID (PATCH_CLASS, 6), CID (FUNCTION, 7), CID (TYPE_PARAMETERS, 8), CID (CLOSURE_DATA, 9), CID (FFI_TRAMPOLINE_DATA, 10), CID (FIELD, 11), CID (SCRIPT, 12), CID (LIBRARY, 13), CID (NAMESPACE, 14), CID (KERNEL_PROGRAM_INFO, 15), CID (WEAK_SERIALIZATION_REFERENCE, 16), CID (WEAK_ARRAY, 17), CID (CODE, 18), CID (OBJECT_POOL, 23), CID (PC_DESCRIPTORS, 24), CID (CODE_SOURCE_MAP, 25), CID (COMPRESSED_STACK_MAPS, 26), CID (EXCEPTION_HANDLERS, 28), CID (CONTEXT, 29), CID (CONTEXT_SCOPE, 30), CID (SENTINEL, 31), CID (SINGLE_TARGET_CACHE, 32), CID (UNLINKED_CALL, 35), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 36), CID (MEGAMORPHIC_CACHE, 37), CID (SUBTYPE_TEST_CACHE, 38), CID (LOADING_UNIT, 39), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (INSTANCE, 45), CID (LIBRARY_PREFIX, 46), CID (TYPE_ARGUMENTS, 47), CID (TYPE, 49), CID (FUNCTION_TYPE, 50), CID (RECORD_TYPE, 51), CID (TYPE_PARAMETER, 52), CID (CLOSURE, 57), CID (MINT, 61), CID (DOUBLE, 62), CID (FLOAT32X4, 64), CID (INT32X4, 65), CID (FLOAT64X2, 66), CID (RECORD, 67), CID (TYPED_DATA, 69), CID (EXTERNAL_TYPED_DATA, 70), CID (TYPED_DATA_VIEW, 71), CID (CAPABILITY, 74), CID (RECEIVE_PORT, 75), CID (SEND_PORT, 76), CID (STACK_TRACE, 77), CID (SUSPEND_STATE, 78), CID (REGEXP, 79), CID (WEAK_PROPERTY, 80), CID (WEAK_REFERENCE, 81), CID (FUTURE_OR, 83), CID (USER_TAG, 84), CID (TRANSFERABLE_TYPED_DATA, 85), CID (MAP, 86), CID (CONST_MAP, 87), CID (SET, 88), CID (CONST_SET, 89), CID (ARRAY, 90), CID (IMMUTABLE_ARRAY, 91), CID (GROWABLE_OBJECT_ARRAY, 92), CID (STRING, 93), CID (ONE_BYTE_STRING, 94), CID (TWO_BYTE_STRING, 95), CID (NUM_PREDEFINED_CIDS, 175) }, 112, 168, 4 },
|
||||
{ "3.11.0", { CID (ILLEGAL, 0), CID (NATIVE_POINTER, 1), CID (CLASS, 5), CID (PATCH_CLASS, 6), CID (FUNCTION, 7), CID (TYPE_PARAMETERS, 8), CID (CLOSURE_DATA, 9), CID (FFI_TRAMPOLINE_DATA, 10), CID (FIELD, 11), CID (SCRIPT, 12), CID (LIBRARY, 13), CID (NAMESPACE, 14), CID (KERNEL_PROGRAM_INFO, 15), CID (WEAK_SERIALIZATION_REFERENCE, 16), CID (WEAK_ARRAY, 17), CID (CODE, 18), CID (OBJECT_POOL, 23), CID (PC_DESCRIPTORS, 24), CID (CODE_SOURCE_MAP, 25), CID (COMPRESSED_STACK_MAPS, 26), CID (EXCEPTION_HANDLERS, 28), CID (CONTEXT, 29), CID (CONTEXT_SCOPE, 30), CID (SENTINEL, 31), CID (SINGLE_TARGET_CACHE, 32), CID (UNLINKED_CALL, 35), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 36), CID (MEGAMORPHIC_CACHE, 37), CID (SUBTYPE_TEST_CACHE, 38), CID (LOADING_UNIT, 39), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (INSTANCE, 45), CID (LIBRARY_PREFIX, 46), CID (TYPE_ARGUMENTS, 47), CID (TYPE, 49), CID (FUNCTION_TYPE, 50), CID (RECORD_TYPE, 51), CID (TYPE_PARAMETER, 52), CID (CLOSURE, 57), CID (MINT, 61), CID (DOUBLE, 62), CID (FLOAT32X4, 64), CID (INT32X4, 65), CID (FLOAT64X2, 66), CID (RECORD, 67), CID (TYPED_DATA, 69), CID (EXTERNAL_TYPED_DATA, 70), CID (TYPED_DATA_VIEW, 71), CID (CAPABILITY, 74), CID (RECEIVE_PORT, 75), CID (SEND_PORT, 76), CID (STACK_TRACE, 77), CID (SUSPEND_STATE, 78), CID (REGEXP, 79), CID (WEAK_PROPERTY, 80), CID (WEAK_REFERENCE, 81), CID (FUTURE_OR, 83), CID (USER_TAG, 84), CID (TRANSFERABLE_TYPED_DATA, 85), CID (MAP, 86), CID (CONST_MAP, 87), CID (SET, 88), CID (CONST_SET, 89), CID (ARRAY, 90), CID (IMMUTABLE_ARRAY, 91), CID (GROWABLE_OBJECT_ARRAY, 92), CID (STRING, 93), CID (ONE_BYTE_STRING, 94), CID (TWO_BYTE_STRING, 95), CID (NUM_PREDEFINED_CIDS, 175) }, 112, 168, 4 },
|
||||
{ "3.12.0", { CID (ILLEGAL, 0), CID (NATIVE_POINTER, 1), CID (CLASS, 5), CID (PATCH_CLASS, 6), CID (FUNCTION, 7), CID (TYPE_PARAMETERS, 8), CID (CLOSURE_DATA, 9), CID (FFI_TRAMPOLINE_DATA, 10), CID (FIELD, 11), CID (SCRIPT, 12), CID (LIBRARY, 13), CID (NAMESPACE, 14), CID (KERNEL_PROGRAM_INFO, 15), CID (WEAK_SERIALIZATION_REFERENCE, 16), CID (WEAK_ARRAY, 17), CID (CODE, 18), CID (OBJECT_POOL, 23), CID (PC_DESCRIPTORS, 24), CID (CODE_SOURCE_MAP, 25), CID (COMPRESSED_STACK_MAPS, 26), CID (EXCEPTION_HANDLERS, 28), CID (CONTEXT, 29), CID (CONTEXT_SCOPE, 30), CID (SENTINEL, 31), CID (SINGLE_TARGET_CACHE, 32), CID (UNLINKED_CALL, 35), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 36), CID (MEGAMORPHIC_CACHE, 37), CID (SUBTYPE_TEST_CACHE, 38), CID (LOADING_UNIT, 39), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (INSTANCE, 45), CID (LIBRARY_PREFIX, 46), CID (TYPE_ARGUMENTS, 47), CID (TYPE, 49), CID (FUNCTION_TYPE, 50), CID (RECORD_TYPE, 51), CID (TYPE_PARAMETER, 52), CID (CLOSURE, 57), CID (MINT, 61), CID (DOUBLE, 62), CID (FLOAT32X4, 64), CID (INT32X4, 65), CID (FLOAT64X2, 66), CID (RECORD, 67), CID (TYPED_DATA, 69), CID (EXTERNAL_TYPED_DATA, 70), CID (TYPED_DATA_VIEW, 71), CID (CAPABILITY, 74), CID (RECEIVE_PORT, 75), CID (SEND_PORT, 76), CID (STACK_TRACE, 77), CID (SUSPEND_STATE, 78), CID (REGEXP, 79), CID (WEAK_PROPERTY, 80), CID (WEAK_REFERENCE, 81), CID (FUTURE_OR, 83), CID (USER_TAG, 84), CID (TRANSFERABLE_TYPED_DATA, 85), CID (MAP, 86), CID (CONST_MAP, 87), CID (SET, 88), CID (CONST_SET, 89), CID (ARRAY, 90), CID (IMMUTABLE_ARRAY, 91), CID (GROWABLE_OBJECT_ARRAY, 92), CID (STRING, 93), CID (ONE_BYTE_STRING, 94), CID (TWO_BYTE_STRING, 95), CID (NUM_PREDEFINED_CIDS, 175) }, 112, 168, 4 },
|
||||
{ "3.13.0", { CID (ILLEGAL, 0), CID (NATIVE_POINTER, 1), CID (CLASS, 5), CID (PATCH_CLASS, 6), CID (FUNCTION, 7), CID (TYPE_PARAMETERS, 8), CID (CLOSURE_DATA, 9), CID (FFI_TRAMPOLINE_DATA, 10), CID (FIELD, 11), CID (SCRIPT, 12), CID (LIBRARY, 13), CID (NAMESPACE, 14), CID (KERNEL_PROGRAM_INFO, 15), CID (WEAK_SERIALIZATION_REFERENCE, 16), CID (WEAK_ARRAY, 17), CID (CODE, 18), CID (OBJECT_POOL, 23), CID (PC_DESCRIPTORS, 24), CID (CODE_SOURCE_MAP, 25), CID (COMPRESSED_STACK_MAPS, 26), CID (EXCEPTION_HANDLERS, 28), CID (CONTEXT, 29), CID (CONTEXT_SCOPE, 30), CID (SENTINEL, 31), CID (SINGLE_TARGET_CACHE, 32), CID (UNLINKED_CALL, 35), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 36), CID (MEGAMORPHIC_CACHE, 37), CID (SUBTYPE_TEST_CACHE, 38), CID (LOADING_UNIT, 39), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (INSTANCE, 45), CID (LIBRARY_PREFIX, 46), CID (TYPE_ARGUMENTS, 47), CID (TYPE, 49), CID (FUNCTION_TYPE, 50), CID (RECORD_TYPE, 51), CID (TYPE_PARAMETER, 52), CID (CLOSURE, 57), CID (MINT, 61), CID (DOUBLE, 62), CID (FLOAT32X4, 64), CID (INT32X4, 65), CID (FLOAT64X2, 66), CID (RECORD, 67), CID (TYPED_DATA, 69), CID (EXTERNAL_TYPED_DATA, 70), CID (TYPED_DATA_VIEW, 71), CID (CAPABILITY, 74), CID (RECEIVE_PORT, 75), CID (SEND_PORT, 76), CID (STACK_TRACE, 77), CID (SUSPEND_STATE, 78), CID (REGEXP, 79), CID (WEAK_PROPERTY, 80), CID (WEAK_REFERENCE, 81), CID (FUTURE_OR, 83), CID (USER_TAG, 84), CID (TRANSFERABLE_TYPED_DATA, 85), CID (MAP, 86), CID (CONST_MAP, 87), CID (SET, 88), CID (CONST_SET, 89), CID (ARRAY, 90), CID (IMMUTABLE_ARRAY, 91), CID (GROWABLE_OBJECT_ARRAY, 92), CID (STRING, 93), CID (ONE_BYTE_STRING, 94), CID (TWO_BYTE_STRING, 95), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
|
||||
{ "3.14.0", { CID (ILLEGAL, 0), CID (NATIVE_POINTER, 1), CID (CLASS, 5), CID (PATCH_CLASS, 6), CID (FUNCTION, 7), CID (TYPE_PARAMETERS, 8), CID (CLOSURE_DATA, 9), CID (FFI_TRAMPOLINE_DATA, 10), CID (FIELD, 11), CID (SCRIPT, 12), CID (LIBRARY, 13), CID (NAMESPACE, 14), CID (KERNEL_PROGRAM_INFO, 15), CID (WEAK_SERIALIZATION_REFERENCE, 16), CID (WEAK_ARRAY, 17), CID (CODE, 18), CID (OBJECT_POOL, 23), CID (PC_DESCRIPTORS, 24), CID (CODE_SOURCE_MAP, 25), CID (COMPRESSED_STACK_MAPS, 26), CID (EXCEPTION_HANDLERS, 28), CID (CONTEXT, 29), CID (CONTEXT_SCOPE, 30), CID (SENTINEL, 31), CID (SINGLE_TARGET_CACHE, 32), CID (UNLINKED_CALL, 35), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 36), CID (MEGAMORPHIC_CACHE, 37), CID (SUBTYPE_TEST_CACHE, 38), CID (LOADING_UNIT, 39), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (INSTANCE, 45), CID (LIBRARY_PREFIX, 46), CID (TYPE_ARGUMENTS, 47), CID (TYPE, 49), CID (FUNCTION_TYPE, 50), CID (RECORD_TYPE, 51), CID (TYPE_PARAMETER, 52), CID (CLOSURE, 57), CID (MINT, 61), CID (DOUBLE, 62), CID (FLOAT32X4, 64), CID (INT32X4, 65), CID (FLOAT64X2, 66), CID (RECORD, 67), CID (TYPED_DATA, 69), CID (EXTERNAL_TYPED_DATA, 70), CID (TYPED_DATA_VIEW, 71), CID (CAPABILITY, 74), CID (RECEIVE_PORT, 75), CID (SEND_PORT, 76), CID (STACK_TRACE, 77), CID (SUSPEND_STATE, 78), CID (REGEXP, 79), CID (WEAK_PROPERTY, 80), CID (WEAK_REFERENCE, 81), CID (FUTURE_OR, 83), CID (USER_TAG, 84), CID (TRANSFERABLE_TYPED_DATA, 85), CID (MAP, 86), CID (CONST_MAP, 87), CID (SET, 88), CID (CONST_SET, 89), CID (ARRAY, 90), CID (IMMUTABLE_ARRAY, 91), CID (GROWABLE_OBJECT_ARRAY, 92), CID (STRING, 93), CID (ONE_BYTE_STRING, 94), CID (TWO_BYTE_STRING, 95), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
|
||||
{ NULL, { 0 }, 0, 0, 0 }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -22,6 +22,16 @@ static bool looks_like_data_snapshot(DartCtx *ctx, ut64 base, ut64 *out_total_le
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dart_snapshot_is_single(DartCtx *ctx, ut64 base) {
|
||||
DartSnapshotHeader hdr;
|
||||
if (!base || !dart_snapshot_header_read (ctx, base, &hdr)) {
|
||||
return false;
|
||||
}
|
||||
const char *version = dart_version_from_hash (hdr.hash);
|
||||
const DartVerLayout *layout = version? dart_profile_from_version (version): NULL;
|
||||
return layout && layout->single_snapshot;
|
||||
}
|
||||
|
||||
static void pick_vm_iso_by_size(const ut64 *addrs, const ut64 *lens, int count, ut64 *vm_out, ut64 *iso_out) {
|
||||
if (count < 1) {
|
||||
return;
|
||||
@@ -157,6 +167,13 @@ static void locate_instr_images_structural(DartCtx *ctx) {
|
||||
if (!vm_instr || vm_instr >= data_lo || !dart_image_at (ctx, vm_instr, data_lo, &sz1)) {
|
||||
return;
|
||||
}
|
||||
if (dart_snapshot_is_single (ctx, ctx->iso_data? ctx->iso_data: ctx->vm_data)) {
|
||||
ctx->iso_instr = vm_instr;
|
||||
if (ctx->verbose > 0) {
|
||||
fprintf (stderr, "[r2flutter] located single instruction image structurally: snapshot_instr=0x%" PFMT64x "\n", (ut64)vm_instr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
ut64 iso_instr = dart_align_up (vm_instr + sz1, DART_IMAGE_ALIGN);
|
||||
if (iso_instr <= vm_instr || iso_instr >= data_lo || !dart_image_at (ctx, iso_instr, data_lo, &sz2)) {
|
||||
return;
|
||||
@@ -194,6 +211,8 @@ int find_snapshots(DartCtx *ctx) {
|
||||
"_kDartIsolateSnapshotInstructions",
|
||||
"DartIsolateSnapshotInstructions",
|
||||
};
|
||||
const char *single_data_names[2] = { "_kDartSnapshotData", "DartSnapshotData" };
|
||||
const char *single_text_names[2] = { "_kDartSnapshotText", "DartSnapshotText" };
|
||||
ut64 *outs[4] = { &ctx->vm_data, &ctx->vm_instr, &ctx->iso_data, &ctx->iso_instr };
|
||||
if (core->bin) {
|
||||
RVecRBinSymbol *v = r_bin_get_symbols_vec (core->bin);
|
||||
@@ -216,12 +235,23 @@ int find_snapshots(DartCtx *ctx) {
|
||||
*outs[idx] = rebase_bin_addr (ctx, sym->vaddr);
|
||||
}
|
||||
}
|
||||
for (int k = 0; k < 2; k++) {
|
||||
if (!strcmp (nm, single_data_names[k]) && sym->vaddr) {
|
||||
ctx->iso_data = rebase_bin_addr (ctx, sym->vaddr);
|
||||
}
|
||||
if (!strcmp (nm, single_text_names[k]) && sym->vaddr) {
|
||||
ctx->iso_instr = rebase_bin_addr (ctx, sym->vaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ctx->vm_data && ctx->vm_instr && ctx->iso_data && ctx->iso_instr) {
|
||||
return 0;
|
||||
}
|
||||
if (ctx->iso_data && ctx->iso_instr && dart_snapshot_is_single (ctx, ctx->iso_data)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
RVecRBinSection *sections = r_bin_get_sections_vec (core->bin);
|
||||
ut64 found_addrs[32];
|
||||
@@ -280,7 +310,11 @@ int find_snapshots(DartCtx *ctx) {
|
||||
// the ones still unset so scan guesses cannot overwrite good values.
|
||||
ut64 scan_vm_data = 0;
|
||||
ut64 scan_iso_data = 0;
|
||||
pick_vm_iso_by_size (data_addrs, data_lens, data_cnt, &scan_vm_data, &scan_iso_data);
|
||||
if (data_cnt == 1 && dart_snapshot_is_single (ctx, data_addrs[0])) {
|
||||
scan_iso_data = data_addrs[0];
|
||||
} else {
|
||||
pick_vm_iso_by_size (data_addrs, data_lens, data_cnt, &scan_vm_data, &scan_iso_data);
|
||||
}
|
||||
if (!ctx->vm_data) {
|
||||
ctx->vm_data = scan_vm_data;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ typedef enum {
|
||||
MODERN_ALLOC_CONTEXT_SCOPE,
|
||||
MODERN_ALLOC_RECORD,
|
||||
MODERN_ALLOC_TYPED_DATA,
|
||||
MODERN_ALLOC_VARIABLE,
|
||||
MODERN_ALLOC_INSTANCE,
|
||||
MODERN_ALLOC_EMPTY,
|
||||
MODERN_ALLOC_UNKNOWN,
|
||||
@@ -39,6 +40,7 @@ typedef enum {
|
||||
MODERN_FILL_INLINE_BYTES,
|
||||
MODERN_FILL_TYPED_DATA,
|
||||
MODERN_FILL_RECORD,
|
||||
MODERN_FILL_CLOSURE,
|
||||
MODERN_FILL_INSTANCE,
|
||||
MODERN_FILL_UNKNOWN,
|
||||
} ModernFillKind;
|
||||
@@ -97,6 +99,7 @@ typedef struct {
|
||||
bool fill_ok;
|
||||
int next_field_offset_words;
|
||||
ut8 *discarded_codes;
|
||||
ut64 *alloc_items;
|
||||
} ModernClusterMeta;
|
||||
|
||||
typedef struct {
|
||||
@@ -258,6 +261,8 @@ static const char *modern_alloc_kind_name(ModernAllocKind kind) {
|
||||
return "record";
|
||||
case MODERN_ALLOC_TYPED_DATA:
|
||||
return "typed_data";
|
||||
case MODERN_ALLOC_VARIABLE:
|
||||
return "variable";
|
||||
case MODERN_ALLOC_INSTANCE:
|
||||
return "instance";
|
||||
case MODERN_ALLOC_EMPTY:
|
||||
@@ -298,6 +303,8 @@ static const char *modern_fill_kind_name(ModernFillKind kind) {
|
||||
return "typed_data";
|
||||
case MODERN_FILL_RECORD:
|
||||
return "record";
|
||||
case MODERN_FILL_CLOSURE:
|
||||
return "closure";
|
||||
case MODERN_FILL_INSTANCE:
|
||||
return "instance";
|
||||
case MODERN_FILL_UNKNOWN:
|
||||
@@ -380,6 +387,7 @@ typedef struct {
|
||||
// handful of clusters. Their readers are gated on this flag; everything
|
||||
// else is shared.
|
||||
bool legacy_format;
|
||||
bool closure_variable;
|
||||
// every CID this layout defines, indexed by kind; -1 when the kind is absent
|
||||
int by_kind[DART_CID_KIND_COUNT];
|
||||
} ModernCidCache;
|
||||
@@ -453,6 +461,7 @@ static ModernCidCache modern_cid_cache_init(const DartVerLayout *layout) {
|
||||
.typed_data_internal_limit = dart_cid_typed_data_limit (layout),
|
||||
.typed_data_stride = dart_cid_typed_data_stride (layout),
|
||||
.legacy_format = modern_layout_is_legacy (layout),
|
||||
.closure_variable = layout && layout->closure_variable,
|
||||
};
|
||||
for (int kind = 0; kind < DART_CID_KIND_COUNT; kind++) {
|
||||
cids.by_kind[kind] = dart_cid_get (layout, (DartCidKind)kind);
|
||||
@@ -603,6 +612,9 @@ static ModernAllocKind modern_alloc_kind(const ModernCidCache *cids, int compres
|
||||
if (modern_cid_eq (cid, cids->double_)) {
|
||||
return MODERN_ALLOC_SIMPLE;
|
||||
}
|
||||
if (cids->closure_variable && modern_cid_eq (cid, cids->closure)) {
|
||||
return MODERN_ALLOC_VARIABLE;
|
||||
}
|
||||
if (modern_is_simple_alloc_cid (cids, cid)) {
|
||||
return MODERN_ALLOC_SIMPLE;
|
||||
}
|
||||
@@ -725,15 +737,25 @@ static bool modern_skip_alloc(ClusterStream *s, const ModernCidCache *cids, int
|
||||
case MODERN_ALLOC_CONTEXT_SCOPE:
|
||||
case MODERN_ALLOC_RECORD:
|
||||
case MODERN_ALLOC_TYPED_DATA:
|
||||
case MODERN_ALLOC_VARIABLE:
|
||||
if (!cs_read_unsigned (s, &count)) {
|
||||
return false;
|
||||
}
|
||||
meta->count = count;
|
||||
if (kind == MODERN_ALLOC_VARIABLE && count) {
|
||||
meta->alloc_items = (ut64 *)calloc ((size_t)count, sizeof (ut64));
|
||||
if (!meta->alloc_items) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (ut64 i = 0; i < count; i++) {
|
||||
ut64 item = 0;
|
||||
if (!cs_read_unsigned (s, &item)) {
|
||||
return false;
|
||||
}
|
||||
if (meta->alloc_items) {
|
||||
meta->alloc_items[i] = item;
|
||||
}
|
||||
modern_cluster_record_item (meta, item);
|
||||
}
|
||||
if ((kind == MODERN_ALLOC_TYPE_ARGUMENTS || kind == MODERN_ALLOC_RODATA) && meta->is_canonical) {
|
||||
@@ -746,6 +768,10 @@ static bool modern_skip_alloc(ClusterStream *s, const ModernCidCache *cids, int
|
||||
if (!cs_read_unsigned (s, &predefined)) {
|
||||
return false;
|
||||
}
|
||||
if (s->ctx && s->ctx->layout && s->ctx->layout->class_alloc_fixed) {
|
||||
meta->count = predefined;
|
||||
return true;
|
||||
}
|
||||
if (cids->num_predefined_cids > 0 && predefined > (ut64)cids->num_predefined_cids) {
|
||||
if (!cs_read_unsigned (s, &predefined)) {
|
||||
return false;
|
||||
@@ -950,6 +976,9 @@ static ModernFillSpec modern_get_fill_spec(const ModernCidCache *cids, int cid)
|
||||
if (modern_cid_eq (cid, cids->record)) {
|
||||
return modern_fill_spec_kind (MODERN_FILL_RECORD);
|
||||
}
|
||||
if (cids->closure_variable && modern_cid_eq (cid, cids->closure)) {
|
||||
return modern_fill_spec_kind (MODERN_FILL_CLOSURE);
|
||||
}
|
||||
static const ModernFillSpecRule rules[] = {
|
||||
{ DART_CID_PATCH_CLASS, MODERN_FILL_REFS, 2, -1, -1, 0, { 0 } },
|
||||
{ DART_CID_TYPE_PARAMETERS, MODERN_FILL_REFS, 4, -1, -1, 0, { 0 } },
|
||||
@@ -1249,6 +1278,24 @@ static bool modern_skip_fill_record(ClusterStream *s, const ModernClusterMeta *m
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool modern_skip_fill_closure(ClusterStream *s, const ModernClusterMeta *meta) {
|
||||
if (!meta->alloc_items && meta->count) {
|
||||
return false;
|
||||
}
|
||||
for (ut64 i = 0; i < meta->count; i++) {
|
||||
ut64 value = 0;
|
||||
if (!cs_read_unsigned (s, &value)) {
|
||||
return false;
|
||||
}
|
||||
for (ut64 j = 0; j < 3 + meta->alloc_items[i]; j++) {
|
||||
if (!cs_read_ref_id (s, &value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool modern_resync_fill_record(ClusterStream *s, const ModernClusterMeta *meta) {
|
||||
if (meta->alloc_items_count != meta->count || !meta->count) {
|
||||
return modern_skip_fill_record (s, meta);
|
||||
@@ -1387,6 +1434,11 @@ static bool modern_skip_fill_object_pool(ClusterStream *s, const ModernClusterMe
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool modern_class_is_top_level(const DartVerLayout *layout, ut32 cid) {
|
||||
const ut32 offset = layout && layout->class_top_level_cid20? 1U << 20: 1U << 16;
|
||||
return cid >= offset;
|
||||
}
|
||||
|
||||
static bool modern_skip_fill_class(ClusterStream *s, const ModernClusterMeta *meta, const ModernFillSpec *spec) {
|
||||
for (ut64 j = 0; j < meta->count; j++) {
|
||||
ut32 class_id = 0;
|
||||
@@ -1401,7 +1453,7 @@ static bool modern_skip_fill_class(ClusterStream *s, const ModernClusterMeta *me
|
||||
return false;
|
||||
}
|
||||
bool is_predefined = j < meta->main_count;
|
||||
bool is_top_level = class_id >= (1U << 16);
|
||||
bool is_top_level = modern_class_is_top_level (s->ctx? s->ctx->layout: NULL, class_id);
|
||||
if (is_predefined || !is_top_level) {
|
||||
ut64 bitmap = 0;
|
||||
if (!cs_read_unsigned (s, &bitmap)) {
|
||||
@@ -1440,6 +1492,8 @@ static bool modern_skip_fill_by_kind(ClusterStream *s, const ModernCidCache *cid
|
||||
return modern_skip_fill_typed_data (s, cids, meta);
|
||||
case MODERN_FILL_RECORD:
|
||||
return modern_resync_fill_record (s, meta);
|
||||
case MODERN_FILL_CLOSURE:
|
||||
return modern_skip_fill_closure (s, meta);
|
||||
case MODERN_FILL_INSTANCE:
|
||||
return modern_skip_fill_instance (s->ctx, s, meta);
|
||||
case MODERN_FILL_NONE:
|
||||
@@ -1862,7 +1916,7 @@ static bool modern_resolver_read_class_fill(ModernWalk *w, ClusterStream *s, con
|
||||
return false;
|
||||
}
|
||||
bool is_predefined = j < meta->main_count;
|
||||
bool is_top_level = class_id >= (1U << 16);
|
||||
bool is_top_level = modern_class_is_top_level (w->ctx? w->ctx->layout: NULL, class_id);
|
||||
if (is_predefined || !is_top_level) {
|
||||
ut64 bitmap = 0;
|
||||
if (!cs_read_unsigned (s, &bitmap)) {
|
||||
@@ -2673,6 +2727,7 @@ static void modern_cluster_meta_free(ModernClusterMeta *meta, ut64 num_clusters)
|
||||
}
|
||||
for (ut64 i = 0; i < num_clusters; i++) {
|
||||
free (meta[i].discarded_codes);
|
||||
free (meta[i].alloc_items);
|
||||
}
|
||||
free (meta);
|
||||
}
|
||||
@@ -2931,7 +2986,7 @@ static bool modern_collect_class_strings(ModernPoolStringRefCollector *collector
|
||||
return false;
|
||||
}
|
||||
bool is_predefined = i < meta->main_count;
|
||||
bool is_top_level = class_id >= (1U << 16);
|
||||
bool is_top_level = modern_class_is_top_level (resolver->ctx? resolver->ctx->layout: NULL, class_id);
|
||||
if (is_predefined || !is_top_level) {
|
||||
ut64 bitmap = 0;
|
||||
if (!cs_read_unsigned (&s, &bitmap)) {
|
||||
@@ -3832,7 +3887,7 @@ static bool modern_read_class_fill(ModernWalk *w, ClusterStream *s, const Modern
|
||||
return false;
|
||||
}
|
||||
bool is_predefined = j < meta->main_count;
|
||||
bool is_top_level = class_id >= (1U << 16);
|
||||
bool is_top_level = modern_class_is_top_level (ctx->layout, class_id);
|
||||
if (is_predefined || !is_top_level) {
|
||||
ut64 bitmap = 0;
|
||||
if (!cs_read_unsigned (s, &bitmap)) {
|
||||
@@ -4140,7 +4195,7 @@ static bool modern_name_scan_read_class(ModernWalk *w, ClusterStream *s, const M
|
||||
if (!cs_read_tagged32 (s, &class_id) || !cs_read_tagged32 (s, &tmp32) || !cs_read_tagged32 (s, &tmp32) || !cs_read_tagged32 (s, &tmp32) || !cs_read_tagged32 (s, &tmp32) || !cs_read_tagged32 (s, &tmp32) || !cs_read_tagged32 (s, &tmp32)) {
|
||||
return false;
|
||||
}
|
||||
const bool is_top_level = class_id >= (1U << 16);
|
||||
const bool is_top_level = modern_class_is_top_level (w->ctx? w->ctx->layout: NULL, class_id);
|
||||
if (j < m->main_count || !is_top_level) {
|
||||
ut64 bitmap = 0;
|
||||
if (!cs_read_unsigned (s, &bitmap)) {
|
||||
|
||||
+68
-28
@@ -135,10 +135,9 @@ static const DartVerLayout *load_layout_from_json(const char *hash, DartVerLayou
|
||||
const char *version = dart_version_from_hash (hash);
|
||||
const DartVerLayout *base_profile = version? dart_profile_from_version (version): NULL;
|
||||
if (!base_profile) {
|
||||
// Unknown hash: fingerprint against the newest known profile so the
|
||||
// decode path (-f/-A) uses the same real layout the -H report shows,
|
||||
// not a degenerate zeroed struct. cws is still refined from the flags.
|
||||
base_profile = dart_newest_profile ();
|
||||
// Keep discovery and decoding on the same conservative profile. A newer
|
||||
// single-snapshot layout requires an exact hash or structural probing.
|
||||
base_profile = dart_fingerprint_profile ();
|
||||
}
|
||||
memcpy (out, base_profile, sizeof (*out));
|
||||
r_str_ncpy (out->hash, hash, sizeof (out->hash));
|
||||
@@ -174,6 +173,10 @@ static DartVerLayout *dart_pick_layout_owned_for_ctx(DartCtx *ctx) {
|
||||
return dart_layout_from_hash (dart_ctx_hash (ctx));
|
||||
}
|
||||
|
||||
static ut64 dart_ctx_primary_data(const DartCtx *ctx) {
|
||||
return ctx? (ctx->vm_data? ctx->vm_data: ctx->iso_data): 0;
|
||||
}
|
||||
|
||||
static void extract_snapshot_hash_flags(DartCtx *ctx, ut64 vm_data) {
|
||||
if (!ctx || !vm_data) {
|
||||
return;
|
||||
@@ -197,11 +200,12 @@ static void extract_snapshot_hash_flags(DartCtx *ctx, ut64 vm_data) {
|
||||
}
|
||||
|
||||
static void derive_layout_from_flags(DartCtx *ctx) {
|
||||
if (!ctx || !ctx->vm_data) {
|
||||
const ut64 data = dart_ctx_primary_data (ctx);
|
||||
if (!ctx || !data) {
|
||||
return;
|
||||
}
|
||||
DartSnapshotHeader hdr;
|
||||
if (!dart_snapshot_header_read (ctx, ctx->vm_data, &hdr)) {
|
||||
if (!dart_snapshot_header_read (ctx, data, &hdr)) {
|
||||
return;
|
||||
}
|
||||
const char *flags = hdr.flags;
|
||||
@@ -230,7 +234,7 @@ static void derive_layout_from_flags(DartCtx *ctx) {
|
||||
}
|
||||
|
||||
DartVerLayout *dart_ctx_init_layout(DartCtx *ctx, DartVerLayout *tmp) {
|
||||
extract_snapshot_hash_flags (ctx, ctx->vm_data);
|
||||
extract_snapshot_hash_flags (ctx, dart_ctx_primary_data (ctx));
|
||||
ctx->layout = R_STR_ISEMPTY (ctx->dart_version_override)? load_layout_from_json (dart_ctx_hash (ctx), tmp): NULL;
|
||||
DartVerLayout *owned = NULL;
|
||||
if (!ctx->layout) {
|
||||
@@ -582,7 +586,7 @@ static int prepare_header_data(DartCtx *ctx) {
|
||||
if (ok != 0) {
|
||||
return -1;
|
||||
}
|
||||
extract_snapshot_hash_flags (ctx, ctx->vm_data);
|
||||
extract_snapshot_hash_flags (ctx, dart_ctx_primary_data (ctx));
|
||||
ctx->layout = dart_pick_layout_owned_for_ctx (ctx);
|
||||
derive_layout_from_flags (ctx);
|
||||
dart_ctx_set_version_source (ctx);
|
||||
@@ -615,6 +619,9 @@ char *dart_pool_dump_header(DartCtx *ctx, int fmt) {
|
||||
pj_kn (pj, "vm_instr", ctx->vm_instr);
|
||||
pj_kn (pj, "iso_data", ctx->iso_data);
|
||||
pj_kn (pj, "iso_instr", ctx->iso_instr);
|
||||
if (ctx->layout && ctx->layout->single_snapshot) {
|
||||
pj_kb (pj, "single_snapshot", true);
|
||||
}
|
||||
if (ctx->container_kind[0]) {
|
||||
pj_k (pj, "container");
|
||||
pj_o (pj);
|
||||
@@ -662,24 +669,33 @@ char *dart_pool_dump_header(DartCtx *ctx, int fmt) {
|
||||
}
|
||||
if (fmt == 'r') {
|
||||
RStrBuf *sb = r_strbuf_new (quiet? "": "'# Dart AOT Snapshot Info\n");
|
||||
const bool single = ctx->layout && ctx->layout->single_snapshot;
|
||||
const ut64 data = dart_ctx_primary_data (ctx);
|
||||
// Create flags for snapshot addresses
|
||||
r_strbuf_appendf (sb, "'fs dart\n");
|
||||
r_strbuf_appendf (sb, "'f dart.vm_data = 0x%" PFMT64x "\n", (ut64)ctx->vm_data);
|
||||
r_strbuf_appendf (sb, "'f dart.vm_instr = 0x%" PFMT64x "\n", (ut64)ctx->vm_instr);
|
||||
r_strbuf_appendf (sb, "'f dart.iso_data = 0x%" PFMT64x "\n", (ut64)ctx->iso_data);
|
||||
r_strbuf_appendf (sb, "'f dart.iso_instr = 0x%" PFMT64x "\n", (ut64)ctx->iso_instr);
|
||||
if (single) {
|
||||
r_strbuf_appendf (sb, "'f dart.snapshot_data = 0x%" PFMT64x "\n", (ut64)ctx->iso_data);
|
||||
r_strbuf_appendf (sb, "'f dart.snapshot_text = 0x%" PFMT64x "\n", (ut64)ctx->iso_instr);
|
||||
r_strbuf_appendf (sb, "'f dart.iso_data = 0x%" PFMT64x "\n", (ut64)ctx->iso_data);
|
||||
r_strbuf_appendf (sb, "'f dart.iso_instr = 0x%" PFMT64x "\n", (ut64)ctx->iso_instr);
|
||||
} else {
|
||||
r_strbuf_appendf (sb, "'f dart.vm_data = 0x%" PFMT64x "\n", (ut64)ctx->vm_data);
|
||||
r_strbuf_appendf (sb, "'f dart.vm_instr = 0x%" PFMT64x "\n", (ut64)ctx->vm_instr);
|
||||
r_strbuf_appendf (sb, "'f dart.iso_data = 0x%" PFMT64x "\n", (ut64)ctx->iso_data);
|
||||
r_strbuf_appendf (sb, "'f dart.iso_instr = 0x%" PFMT64x "\n", (ut64)ctx->iso_instr);
|
||||
}
|
||||
if (ctx->container_kind[0]) {
|
||||
r_strbuf_appendf (sb, "'f dart.container_payload = 0x%" PFMT64x "\n", (ut64)ctx->container_payload_offset);
|
||||
r_strbuf_appendf (sb, "'f dart.container_payload_size = 0x%" PFMT64x "\n", (ut64)ctx->container_payload_size);
|
||||
}
|
||||
if (!quiet) {
|
||||
// Add comments with metadata
|
||||
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC Dart snapshot hash: %s\n", (ut64)ctx->vm_data, ctx->snapshot_hash[0]? ctx->snapshot_hash: "(unknown)");
|
||||
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC Dart version: %s (%s)\n", (ut64)ctx->vm_data, version, version_source);
|
||||
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC Dart snapshot hash: %s\n", data, ctx->snapshot_hash[0]? ctx->snapshot_hash: "(unknown)");
|
||||
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC Dart version: %s (%s)\n", data, version, version_source);
|
||||
if (ctx->layout) {
|
||||
const DartVerLayout *l = ctx->layout;
|
||||
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC Tag style: %s\n", (ut64)ctx->vm_data, dart_tag_style_to_string (l->tag_style));
|
||||
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC Alignment: %d, CWS: %d\n", (ut64)ctx->vm_data, l->max_alignment, ctx->compressed_word_size);
|
||||
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC Tag style: %s\n", data, dart_tag_style_to_string (l->tag_style));
|
||||
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC Alignment: %d, CWS: %d\n", data, l->max_alignment, ctx->compressed_word_size);
|
||||
}
|
||||
}
|
||||
return r_strbuf_drain (sb);
|
||||
@@ -691,6 +707,9 @@ char *dart_pool_dump_header(DartCtx *ctx, int fmt) {
|
||||
if (ctx->layout) {
|
||||
const DartVerLayout *l = ctx->layout;
|
||||
r_strbuf_appendf (sb, " tag_style=%s alignment=%d", dart_tag_style_to_string (l->tag_style), l->max_alignment);
|
||||
if (l->single_snapshot) {
|
||||
r_strbuf_append (sb, " single_snapshot=true");
|
||||
}
|
||||
}
|
||||
return r_strbuf_drain (sb);
|
||||
}
|
||||
@@ -708,10 +727,15 @@ char *dart_pool_dump_header(DartCtx *ctx, int fmt) {
|
||||
}
|
||||
|
||||
r_strbuf_appendf (sb, "\n## Snapshot Addresses\n");
|
||||
r_strbuf_appendf (sb, "vm_data: 0x%" PFMT64x "\n", (ut64)ctx->vm_data);
|
||||
r_strbuf_appendf (sb, "vm_instr: 0x%" PFMT64x "\n", (ut64)ctx->vm_instr);
|
||||
r_strbuf_appendf (sb, "iso_data: 0x%" PFMT64x "\n", (ut64)ctx->iso_data);
|
||||
r_strbuf_appendf (sb, "iso_instr: 0x%" PFMT64x "\n", (ut64)ctx->iso_instr);
|
||||
if (ctx->layout && ctx->layout->single_snapshot) {
|
||||
r_strbuf_appendf (sb, "snapshot_data: 0x%" PFMT64x "\n", (ut64)ctx->iso_data);
|
||||
r_strbuf_appendf (sb, "snapshot_text: 0x%" PFMT64x "\n", (ut64)ctx->iso_instr);
|
||||
} else {
|
||||
r_strbuf_appendf (sb, "vm_data: 0x%" PFMT64x "\n", (ut64)ctx->vm_data);
|
||||
r_strbuf_appendf (sb, "vm_instr: 0x%" PFMT64x "\n", (ut64)ctx->vm_instr);
|
||||
r_strbuf_appendf (sb, "iso_data: 0x%" PFMT64x "\n", (ut64)ctx->iso_data);
|
||||
r_strbuf_appendf (sb, "iso_instr: 0x%" PFMT64x "\n", (ut64)ctx->iso_instr);
|
||||
}
|
||||
if (ctx->container_kind[0]) {
|
||||
r_strbuf_appendf (sb, "\n## Container\n");
|
||||
r_strbuf_appendf (sb, "kind: %s\n", ctx->container_kind);
|
||||
@@ -721,8 +745,9 @@ char *dart_pool_dump_header(DartCtx *ctx, int fmt) {
|
||||
r_strbuf_appendf (sb, "macho_off: 0x%" PFMT64x "\n", (ut64)ctx->container_macho_offset);
|
||||
}
|
||||
|
||||
ut64 addrs[2] = { ctx->vm_data, ctx->iso_data };
|
||||
const char *labels[2] = { "VM", "Isolate" };
|
||||
const bool single = ctx->layout && ctx->layout->single_snapshot;
|
||||
ut64 addrs[2] = { single? ctx->iso_data: ctx->vm_data, single? 0: ctx->iso_data };
|
||||
const char *labels[2] = { single? "Combined": "VM", "Isolate" };
|
||||
for (int si = 0; si < 2; si++) {
|
||||
if (!addrs[si]) {
|
||||
continue;
|
||||
@@ -840,6 +865,9 @@ static char *dump_header_ext_json(DartCtx *ctx, int detail) {
|
||||
pj_kn (pj, "vm_instr", ctx->vm_instr);
|
||||
pj_kn (pj, "iso_data", ctx->iso_data);
|
||||
pj_kn (pj, "iso_instr", ctx->iso_instr);
|
||||
if (ctx->layout && ctx->layout->single_snapshot) {
|
||||
pj_kb (pj, "single_snapshot", true);
|
||||
}
|
||||
pj_ki (pj, "cws", ctx->compressed_word_size);
|
||||
pj_ks (pj, "dart_version", version);
|
||||
pj_ks (pj, "version_source", dart_version_source_str (ctx? ctx->version_source: DART_VERSION_SOURCE_UNKNOWN));
|
||||
@@ -875,8 +903,12 @@ static char *dump_header_ext_json(DartCtx *ctx, int detail) {
|
||||
pj_end (pj);
|
||||
}
|
||||
pj_ka (pj, "snapshots");
|
||||
dump_header_snapshot_json (ctx, pj, "VM", ctx->vm_data, detail);
|
||||
dump_header_snapshot_json (ctx, pj, "Isolate", ctx->iso_data, detail);
|
||||
if (ctx->layout && ctx->layout->single_snapshot) {
|
||||
dump_header_snapshot_json (ctx, pj, "Combined", ctx->iso_data, detail);
|
||||
} else {
|
||||
dump_header_snapshot_json (ctx, pj, "VM", ctx->vm_data, detail);
|
||||
dump_header_snapshot_json (ctx, pj, "Isolate", ctx->iso_data, detail);
|
||||
}
|
||||
pj_end (pj);
|
||||
pj_end (pj);
|
||||
return pj_drain (pj);
|
||||
@@ -970,15 +1002,23 @@ static char *dart_pool_dump_header_ext_level(DartCtx *ctx, int fmt, int detail)
|
||||
char *header = dart_pool_dump_header (ctx, fmt);
|
||||
RStrBuf *sb = r_strbuf_new (header? header: "");
|
||||
free (header);
|
||||
dump_header_ext_snapshot_r2 (ctx, sb, "VM", "vm", ctx->vm_data, detail);
|
||||
dump_header_ext_snapshot_r2 (ctx, sb, "Isolate", "isolate", ctx->iso_data, detail);
|
||||
if (ctx->layout && ctx->layout->single_snapshot) {
|
||||
dump_header_ext_snapshot_r2 (ctx, sb, "Combined", "snapshot", ctx->iso_data, detail);
|
||||
} else {
|
||||
dump_header_ext_snapshot_r2 (ctx, sb, "VM", "vm", ctx->vm_data, detail);
|
||||
dump_header_ext_snapshot_r2 (ctx, sb, "Isolate", "isolate", ctx->iso_data, detail);
|
||||
}
|
||||
return r_strbuf_drain (sb);
|
||||
}
|
||||
char *header = dart_pool_dump_header (ctx, fmt);
|
||||
RStrBuf *sb = r_strbuf_new (header? header: "");
|
||||
free (header);
|
||||
dump_header_ext_snapshot_text (ctx, sb, "VM", ctx->vm_data, detail);
|
||||
dump_header_ext_snapshot_text (ctx, sb, "Isolate", ctx->iso_data, detail);
|
||||
if (ctx->layout && ctx->layout->single_snapshot) {
|
||||
dump_header_ext_snapshot_text (ctx, sb, "Combined", ctx->iso_data, detail);
|
||||
} else {
|
||||
dump_header_ext_snapshot_text (ctx, sb, "VM", ctx->vm_data, detail);
|
||||
dump_header_ext_snapshot_text (ctx, sb, "Isolate", ctx->iso_data, detail);
|
||||
}
|
||||
return r_strbuf_drain (sb);
|
||||
}
|
||||
|
||||
|
||||
+47
-32
@@ -125,36 +125,42 @@ static const struct {
|
||||
// Dart 3.12.x
|
||||
{ "41be3daaabd524b8aa7423bc24584957", "3.12.0" },
|
||||
{ "ace654289f5abc240509fc941453ebc5", "3.12.1" },
|
||||
// Dart 3.13.x
|
||||
{ "0451907c2eaa8467e848c0067bfe8ed4", "3.13.0" },
|
||||
// Dart 3.14.x
|
||||
{ "7a1ea3f6f5cf1089a7f6e55d7f20dbfd", "3.14.0" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// Range-start version profiles. CID tables are generated in dart_cid.c.
|
||||
static const DartVerLayout version_profiles[] = {
|
||||
{ "", "2.10.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_INT32, 4, DART_HEADER_STYLE_210, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_DEFERRED_ONLY, 7, 0, true }, // Dart 2.10.0
|
||||
{ "", "2.12.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_INT32, 5, DART_HEADER_STYLE_212, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_DEFERRED_ONLY, 7, 0, true }, // Dart 2.12.0
|
||||
{ "", "2.13.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_INT32, 5, DART_HEADER_STYLE_212, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_DEFERRED_ONLY, 7, 0, true }, // Dart 2.13.0
|
||||
{ "", "2.14.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_214, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 7, 0, true }, // Dart 2.14.0
|
||||
{ "", "2.15.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_214, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 7, 0, true }, // Dart 2.15.0
|
||||
{ "", "2.16.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 6, DART_HEADER_STYLE_216, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 7, 0, false }, // Dart 2.16.0
|
||||
{ "", "2.17.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 6, DART_HEADER_STYLE_216, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 2.17.0
|
||||
{ "", "2.18.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 2.18.0
|
||||
{ "", "2.18.2", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 2.18.2
|
||||
{ "", "2.18.3", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 2.18.3
|
||||
{ "", "2.19.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 2.19.0
|
||||
{ "", "3.0.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.0.0
|
||||
{ "", "3.1.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.1.0
|
||||
{ "", "3.2.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7_SWAPPED, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.2.0
|
||||
{ "", "3.3.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.3.0
|
||||
{ "", "3.4.0", 8, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.4.0
|
||||
{ "", "3.5.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.5.0
|
||||
{ "", "3.6.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.6.0
|
||||
{ "", "3.7.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.7.0
|
||||
{ "", "3.8.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.8.0
|
||||
{ "", "3.9.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.9.0
|
||||
{ "", "3.10.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.10.0
|
||||
{ "", "3.11.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.11.0
|
||||
{ "", "3.12.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false }, // Dart 3.12.0
|
||||
{ { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
{ "", "2.10.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_INT32, 4, DART_HEADER_STYLE_210, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_DEFERRED_ONLY, 7, 0, true, false, false, false, false }, // Dart 2.10.0
|
||||
{ "", "2.12.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_INT32, 5, DART_HEADER_STYLE_212, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_DEFERRED_ONLY, 7, 0, true, false, false, false, false }, // Dart 2.12.0
|
||||
{ "", "2.13.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_INT32, 5, DART_HEADER_STYLE_212, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_DEFERRED_ONLY, 7, 0, true, false, false, false, false }, // Dart 2.13.0
|
||||
{ "", "2.14.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_214, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 7, 0, true, false, false, false, false }, // Dart 2.14.0
|
||||
{ "", "2.15.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_214, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 7, 0, true, false, false, false, false }, // Dart 2.15.0
|
||||
{ "", "2.16.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 6, DART_HEADER_STYLE_216, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 7, 0, false, false, false, false, false }, // Dart 2.16.0
|
||||
{ "", "2.17.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 6, DART_HEADER_STYLE_216, DART_REF_ENCODING_UNSIGNED, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, false }, // Dart 2.17.0
|
||||
{ "", "2.18.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, false }, // Dart 2.18.0
|
||||
{ "", "2.18.2", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, false }, // Dart 2.18.2
|
||||
{ "", "2.18.3", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, false }, // Dart 2.18.3
|
||||
{ "", "2.19.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 2.19.0
|
||||
{ "", "3.0.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.0.0
|
||||
{ "", "3.1.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.1.0
|
||||
{ "", "3.2.0", 8, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_LOW7_SWAPPED, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.2.0
|
||||
{ "", "3.3.0", 4, 1, 16, 20000, DART_TAG_STYLE_CID_SHIFT1, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.3.0
|
||||
{ "", "3.4.0", 8, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.4.0
|
||||
{ "", "3.5.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.5.0
|
||||
{ "", "3.6.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.6.0
|
||||
{ "", "3.7.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.7.0
|
||||
{ "", "3.8.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.8.0
|
||||
{ "", "3.9.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.9.0
|
||||
{ "", "3.10.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.10.0
|
||||
{ "", "3.11.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.11.0
|
||||
{ "", "3.12.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 0, false, false, false, false, true }, // Dart 3.12.0
|
||||
{ "", "3.13.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 2, false, true, true, true, true }, // Dart 3.13.0
|
||||
{ "", "3.14.0", 4, 1, 16, 20000, DART_TAG_STYLE_OBJECT_HEADER, 5, DART_HEADER_STYLE_MODERN, DART_REF_ENCODING_REF_ID128, DART_POOL_ENCODING_MODERN, DART_CODE_ALLOC_STATE_DEFERRED, 6, 2, false, true, true, true, true }, // Dart 3.14.0
|
||||
{ { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
const char *dart_version_from_hash(const char *hash) {
|
||||
@@ -177,6 +183,16 @@ const DartVerLayout *dart_newest_profile(void) {
|
||||
return newest;
|
||||
}
|
||||
|
||||
const DartVerLayout *dart_fingerprint_profile(void) {
|
||||
const DartVerLayout *baseline = version_profiles;
|
||||
for (int i = 0; version_profiles[i].dart_version; i++) {
|
||||
if (!version_profiles[i].single_snapshot) {
|
||||
baseline = &version_profiles[i];
|
||||
}
|
||||
}
|
||||
return baseline;
|
||||
}
|
||||
|
||||
const char *dart_version_source_str(int source) {
|
||||
switch (source) {
|
||||
case DART_VERSION_SOURCE_EXACT:
|
||||
@@ -222,17 +238,16 @@ DartVerLayout *dart_layout_from_hash(const char *hash) {
|
||||
}
|
||||
return dvl;
|
||||
}
|
||||
// Unknown hash: fingerprint against the newest known profile. Snapshot
|
||||
// formats (CID tables, tag style) only change at release boundaries, so an
|
||||
// unlisted git/dev build almost always matches the most recent release; the
|
||||
// caller still refines compressed_word_size from the feature flags.
|
||||
const DartVerLayout *newest = dart_newest_profile ();
|
||||
memcpy (dvl, newest, sizeof (DartVerLayout));
|
||||
// A single-snapshot profile changes discovery as well as cluster framing, so
|
||||
// an unknown hash must not inherit one without structural evidence. Keep the
|
||||
// newest compatible split-snapshot baseline until probing selects a layout.
|
||||
const DartVerLayout *baseline = dart_fingerprint_profile ();
|
||||
memcpy (dvl, baseline, sizeof (DartVerLayout));
|
||||
if (hash && *hash) {
|
||||
r_str_ncpy (dvl->hash, hash, sizeof (dvl->hash));
|
||||
}
|
||||
if (G_VERBOSE > 0) {
|
||||
fprintf (stderr, "[r2flutter] Unknown snapshot hash, fingerprinting as newest known profile %s (hash=%s)\n", newest->dart_version, hash? hash: "(null)");
|
||||
fprintf (stderr, "[r2flutter] Unknown snapshot hash, fingerprinting as compatible profile %s (hash=%s)\n", baseline->dart_version, hash? hash: "(null)");
|
||||
}
|
||||
return dvl;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
NAME=dart-313-single-snapshot-layout
|
||||
FILE=-
|
||||
CMDS=<<EOF
|
||||
!!python3 -c 'import sys; open(sys.argv[1], "wb").write(bytes.fromhex(sys.argv[2]))' /tmp/r2flutter-single-313.bin 50414421f5f5dcdc97000000000000000200000000000000303435313930376332656161383436376538343863303036376266653865643470726f647563742061726d3634206e6f2d636f6d707265737365642d706f696e746572730082868485890020c1810040c481c0800020ce81820060c58181808080808080808080808080807022c4c4c3c0c0c0c080808087808080808080808080808080810181
|
||||
!!../bin/r2flutter -q -j -HHH -l 8 /tmp/r2flutter-single-313.bin 2>/dev/null | python3 -c 'import json,sys; d=json.load(sys.stdin); s=d["snapshots"][0]; c={x["cid"]:x for x in s["clusters"]}; e=c[23]["object_pools"][0]["entries"][0]; print(d["dart_version"], d["single_snapshot"], d["vm_data"], d["iso_data"], len(d["snapshots"]), s["label"], s["clusters_parsed"]); print(c[5]["alloc"], c[5]["fill_status"], c[18]["fill_status"], c[57]["alloc"], c[57]["fill"], c[57]["items"]["total"], e["ref"])'
|
||||
!!python3 -c 'import sys; open(sys.argv[1], "wb").write(bytes.fromhex(sys.argv[2]))' /tmp/r2flutter-single-314.bin 50414421f5f5dcdc97000000000000000200000000000000376131656133663666356366313038396137663665353564376632306462666470726f647563742061726d3634206e6f2d636f6d707265737365642d706f696e746572730082868485890020c1810040c481c0800020ce81820060c58181808080808080808080808080807022c4c4c3c0c0c0c080808087808080808080808080808080810181
|
||||
!!../bin/r2flutter -q -j -H /tmp/r2flutter-single-314.bin 2>/dev/null | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["dart_version"], d["single_snapshot"], d["vm_data"], d["iso_data"], d["cid_table"]["num_predefined"])'
|
||||
!!python3 -c 'import sys; open(sys.argv[1], "wb").write(bytes.fromhex(sys.argv[2]))' /tmp/r2flutter-single-313-truncated.bin 50414421f5f5dcdc92000000000000000200000000000000303435313930376332656161383436376538343863303036376266653865643470726f647563742061726d3634206e6f2d636f6d707265737365642d706f696e746572730082868485890020c1810040c481c0800020ce81820060c58181808080808080808080808080807022c4c4c3c0c0c0c08080808780808080808080808080
|
||||
!!../bin/r2flutter -q -j -HHH -l 8 /tmp/r2flutter-single-313-truncated.bin 2>/dev/null | python3 -c 'import json,sys; d=json.load(sys.stdin); s=d["snapshots"][0]; c={x["cid"]:x for x in s["clusters"]}; print("truncated", d["dart_version"], s["label"], s["clusters_parsed"], c[57]["fill_status"], c[23]["fill_status"], c[23]["object_pool_decode"])'
|
||||
!!rm -f /tmp/r2flutter-single-313.bin /tmp/r2flutter-single-314.bin /tmp/r2flutter-single-313-truncated.bin
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
3.13.0 True 0 4 1 Combined True
|
||||
class ok ok variable closure 2 1
|
||||
3.14.0 True 0 4 176
|
||||
truncated 3.13.0 Combined True failed not_parsed fill_not_parsed
|
||||
EOF
|
||||
RUN
|
||||
Reference in new issue
Block a user