50 Commits
Author SHA1 Message Date
pancake 02b0b84fa6 Release 0.6.0 2026-11-06 14:03:14 +01:00
pancake 0ee5e01498 Give duplicate Dart method names unique r2 flags and function names
r2 flag names are unique, so flagging a second function with a repeated
Dart name (e.g. Native._anon_closure) moved the flag away from the first
one, and current r2's af then named it after the Mach-O sym.func.* flag.
Suffix repeats with their address, use the same names for afs, and rename
analyzed functions after the af pass.

Also skip var recovery, call-following and jump tables in the signature
af pass (AuthPass -AAA 47s -> 29s) and raise R2R_TIMEOUT to 60s.
2026-11-06 13:54:07 +01:00
pancake cc338995cf Update mafia -z goldens for VM base-object pool strings 2026-11-06 13:37:57 +01:00
pancake 8a9e54be29 Support RVec fcn->bbs on R2_ABIVERSION >= 168 2026-11-05 12:57:12 +01:00
pancake 441d614937 Scan complete instruction ranges for standalone xrefs 2026-10-21 12:47:42 +02:00
pancake 25a5b3f026 Decode Record fields in snapshot value graphs 2026-10-21 12:46:56 +02:00
pancake 3bfdd5601a Resolve direct ObjectPool Code targets 2026-10-21 12:20:58 +02:00
pancake 84a25ea38c Resolve ObjectPool Field names and owners 2026-10-21 12:12:31 +02:00
pancake 2bf613618f Propagate ObjectPool collection strings into analysis 2026-10-21 10:52:18 +02:00
pancake a2fd82106e Include ObjectPool instance strings in -z output 2026-10-21 10:39:11 +02:00
pancake bd6f596279 Fix ObjectPool string xrefs through instance fields 2026-10-21 09:32:21 +02:00
pancake 7be0c178fb Release 0.5.1 2026-10-16 03:04:52 +02:00
pancake 3552d7485c Update class metadata golden for quoted pf output 2026-10-16 03:04:40 +02:00
pancake 878a588adf Release 0.5.0 2026-10-16 00:26:17 +02:00
pancake d0215dbfc2 Use r2-6.2.4 2026-10-16 00:26:09 +02:00
pancake 3cef0ce07a Fix signed 64-bit varint decoding
cs_read_tagged64 biased the final byte by -64 instead of -192, adding
128 << shift to every Mint/Smi value, which inflated field offsets and
decoded constants.
2026-10-09 16:05:25 +02:00
pancake 7d019ea748 Resolve class method entry points
Map each Function's code index (a raw InstructionTable slot, including
discarded-Code slots) to its entry address. Class-derived names only
replace placeholder names when merged into the function list, so
InstructionTable names stay authoritative for deduplicated code.
2026-10-09 16:05:23 +02:00
pancake f7c6cc5b3d Extract class metadata from Dart 2.14-3.3 snapshots
modern_can_extract_classes only accepted OBJECT_HEADER (3.4+) snapshots,
so CID_SHIFT1 apps such as Dart 2.19 fell back to the string heuristic
after the legacy parser failed. Gate on modern_supported instead.
2026-10-09 16:05:20 +02:00
pancake 24e3502737 Complete code xrefs for Dart 2.19 2026-10-06 17:50:40 +02:00
pancake 78719df43e Fix Dart 2.19 ObjectPool xrefs after Type fill parsing 2026-10-06 17:30:45 +02:00
pancake 3fe3c11bac Register the r2flutter pkg 2026-10-06 16:55:12 +02:00
pancake fa854fb648 Release 0.4.0 2026-10-06 00:43:14 +02:00
pancake a9efd1d262 doc: record x86-64 Dart AOT scan support 2026-10-02 12:33:45 +02:00
pancake 01db9e6b54 Seed anal.gp with the right PP register per arch
r2flutter_setup_pp_gp now sets anal.gpseed/anal.roregs to r15 on x86-64 and
x27 on arm64, so plain-r2 ESIL resolves [PP, off] pool loads on both.
2026-10-02 12:33:43 +02:00
pancake abcdbb2b11 Resolve x86-64 pool slots by adding back the heap tag
On x86-64 the pool pointer r15 carries the heap tag, so a [r15, off]
instruction offset is one less than the collector/arm64 slot offset. Detect
x64 from asm.arch/bits and add the tag (+1) back to get the canonical slot
offset used for the string/ref map lookups and the pool-slot address.

This makes the whole chain line up on x64: the code->pool-slot xref now lands
on the same slot the data-image string ref targets, pool strings resolve
inline, and a real code->string xref is emitted. On the Android x86_64 app
axt 0x76a97 now shows 'method.DioManager.initParams ... mov rax, [r15 +
str.https:__pss.aakredit.in_]' with the value inlined; resolved strings went
1455 -> 7411. arm64 is unchanged (slot_off == pp_off).
2026-10-02 12:33:40 +02:00
pancake 05ebbd2c2d Detect x86-64 pool loads and xref the pool slot from code
- flutter_reg_is_pp now recognises r15 (x64 PP) alongside x27 (arm64).
- Reclassify x86-64 'mov reg,[mem]' / 'mov [mem],reg' (typed MOV by r2) as
  LOAD/STORE via an effective op type, so the pool-load logic runs on x64.
- Emit a code->pool-slot xref (pp_base + off) on every pool load, for both
  arches, so axt on a slot shows the loading code - the 'link code to the PP
  table' that was missing.
- Drop the (pp_off & 7) alignment guard: it assumed arm64's even PP base and
  rejected x64's tagged-base odd offsets, and the has_pp_slot fix already
  prevents the field-deref it guarded against (arm64 still shows 0 misaligned).

x64 (an Android x86_64 app) went from 0 to 36467 PP refs; arm64 is unchanged
(w0rdle still 27388 PP refs, 0 misaligned).
2026-10-02 12:33:37 +02:00
pancake cd90ffe555 Recognize x86-64 registers and operand syntax in the scan
Add an x86-64 general-purpose register name->slot mapping (rax..r15, 32-bit
aliases) to flutter_reg_index and accept the x64 '[reg + disp]' memory operand
form alongside arm64's '[reg, disp]'. Foundation for scanning x64 Dart AOT
snapshots; arm64 behaviour is unchanged (names never collide).
2026-10-02 12:33:35 +02:00
pancake 05c0616b37 Add r2flutter.str options to configure string parsing limits 2026-10-01 17:41:24 +02:00
pancake 49f174f3cd Fix extras tests for tiered -A/-AA/-AAA and the analysis log line
- r2flutter-help: the help now lists -A/-AA/-AAA separately instead of
  -A[AA], so update both expected copies.
- analysis: run -qAAA and drop the EXPECT_ERR count line. The summary now
  carries the graph-xref count and the x22 fix changed the PP-ref total, and
  those counts also drift with the r2 build; the version-independent
  dart.class flag list remains the real assertion.
2026-10-01 17:01:12 +02:00
pancake cfb6448172 Dartpool refs moved into -AA and speedup AAA 2026-10-01 16:46:58 +02:00
pancake b7f425ca97 Apply dart pool refs to actual data strings with -AAA 2026-10-01 16:34:11 +02:00
pancake db30ebcb55 Annotate NULL_REG (x22) null/true/false idioms in -AAA
x22 caches Object::null() program-wide; the VM places null/true/false as
adjacent heap objects, so the compiler materialises booleans with add off
NULL_REG (true = null+0x20, false = null+0x30 on arm64, constant across Dart
versions and pointer compression). The scan now comments add x22,#0x20/#0x30
as true/false, mov from x22 as null, and compares against x22 as null checks -
the primitive the certificate-pinning bypass keys on. Verified on iOS
(cws=8) and Android (cws=4).
2026-10-01 14:30:49 +02:00
pancake 5651efc492 Expose the ObjectPool as anal.gp in r2flutter-A
x27/PP is the only Dart reserved register with a static address (the pool is
in the snapshot). r2flutter -A now seeds anal.gp with the pool base,
anal.gpseed=x27, anal.roregs=x27,gp,zero and an 'f PP' flag, so plain-r2
analysis/ESIL resolves [x27, off] pool loads - matching what -p -r already
set up. Resolution runs on a shallow DartCtx copy so the per-command read
cache (ctx->rmem) is not shared into the analysis DartApp and double-freed.
2026-10-01 14:30:46 +02:00
pancake a6fc7e4829 Fix PP mis-identification: a loaded pool value is not a PP pointer
The tracker marked the destination of a pool load as a PP pointer, so a later
[dst, field] deref was read as another slot: ldr x30,[x27,0x18] (a Code
object) then ldur x30,[x30,7] (entry-point) produced a bogus PP slot +0x1f,
and the blr reported 'indirect call via PP+0x1f'. Now:
- pp_load tags the dest with has_pp_slot/pp_slot (the slot it came from),
  never has_pp_off;
- flutter_process_pp_slot_deref carries that taint across the entry-point
  deref so the blr names the real slot and can xref it;
- a hard guard rejects any pp_off & 7, since valid slots are always
  word-aligned ((index+2)*8), killing every misaligned +0x..7 bogus comment.
2026-10-01 12:23:36 +02:00
pancake d0467e4e41 Resolve PP-slot comments to kind/name and add xrefs
After -AAA, non-string PP slots were left as bare 'dart: PP slot +0x..'
comments even though -O resolves them by hand. Resolve every slot up front
with modern_collect_direct_pool_refs and, in the analysis:
- inline the resolved name for function/class slots,
- add a navigable xref to the entrypoint for code/function slots (CALL for
  blr, DATA otherwise), mapping code_index through the instruction table,
- label every remaining slot by its kind, so none stays a bare offset.
2026-10-01 12:23:31 +02:00
pancake f35d5b569d 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.
2026-10-01 12:23:28 +02:00
pancake 2396599251 Clear dangling ctx->layout in the PP-string loader
dart_ctx_init_layout returns NULL (not an owned layout) when it loads the
layout into the caller's stack tmp buffer, leaving ctx->layout pointing at
that stack. The loader only cleared it when an owned layout came back, so on
return ctx->layout dangled and the next consumer of the shared DartCtx read
through freed stack. Clear it whenever we initialised it, regardless of the
return value.
2026-10-01 12:23:22 +02:00
pancake 7d283902f3 Support pre r2-6.2.4 triplets 2026-09-30 11:32:54 +02:00
pancake 30b8fe76d9 Improve the ci builds to make binary r2pm possible 2026-09-30 11:10:21 +02:00
fatalSecandClaude Opus 5 67935055e5 Speed up -AAA on large snapshots without changing its results
On a 37,863-function Dart 3.13 iOS app `r2flutter -AAA` took 19 minutes
(1,136s). Three costs grew with snapshot size:

- read_mem cached a single 1 MB window. modern_load_rodata_strings
  alternates between a cluster alloc stream and the RO data image
  megabytes away, so each string refilled the window twice (a 1 MB read
  plus the 0xff fill r_io_bank_read_at does first). Keep four windows
  with LRU eviction. Move the cache behind a pointer so DartCtx copies
  (flutter_model_load, dart_recovery_model_load) share buffers together
  with their addresses instead of leaving the original with stale ones,
  and drop a window whose refill failed since the failed read already
  overwrote it. `-f` 12.4s -> 0.5s; -c/-i/-T/-S ~6s -> <0.25s.

- afs stores prototypes through r_anal_save_parsed_type, which calls
  r_anal_remove_parsed_type for each declared type. For an existing name
  that sorts and scans the whole type database although r_type_del has
  already removed every key of a function type. Names repeat often:
  anonymous closures, and names the C parser cuts at ':' (dyn:call is
  stored as `call`). Parse the prototype with r_anal_cparse and
  r_type_del those names first so afs takes its early return. The
  signature pass went from 1,127s to 27s.

- With anal.trycatch (the radare2 6.2.2 default) every af walks all flags
  twice for try.<addr>.catch|filter. After -AAA creates its flags that is
  O(flags) per function. Disable it around r2flutter's af loops when no
  try.* flag exists, which cannot change the result.

-AAA now takes 36s on that app (35s -> 6s on a smaller 3.13 build). A
dump of afl, afs @@F, f, CC and ax after -AAA is byte-identical to the
previous build on both apps (796,194 and 138,032 lines), and so is stderr.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01KmxPHTVwSkr2HTHJHQsord
2026-09-19 00:17:15 +08:00
FatalSec 5c4a51d5fb Fix Dart 3.13 ObjectPool decode: parse early base-object clusters
- Support Dart 3.13 combined VM snapshots
- Add CID kinds and layouts for LocalVarDescriptors, ApiError, and UnwindError
- Fix stream desync causing "PP not resolved" in `r2flutter -p`
- Skip zero-length ObjectPools when resolving PP slots
2026-09-16 07:48:42 +08:00
FatalSec e8bf641f91 Fix CID_SHIFT1 ObjectPool decode: PatchClass has 2 refs on Dart 3.0-3.3 2026-09-13 23:23:07 +08:00
pancake 3e12922ba0 Release 0.3.6 2026-09-08 13:30:40 +02:00
pancake 42b606ae7f Build the debian package in the ci 2026-09-08 13:30:06 +02:00
pancake 507994deda Add dist/debian 2026-09-08 13:26:00 +02:00
pancakeandClaude Opus 5 ce97e96eda Ship the r2 plugin in the windows zip and strip the binaries before packaging
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EUoqrdf1quwjg3MsThyq1B
2026-09-08 11:50:25 +02:00
pancake 2f8343b97b Release 0.3.4 2026-09-08 11:14:04 +02:00
pancake 5394a6f6e6 Use r_str_tok_r in the sbom parser to link on windows 2026-09-08 09:52:56 +02:00
pancake b2d8a4917a Fix the windows build by avoiding posix-only apis and translating the r2 flags for msvc 2026-09-08 09:52:56 +02:00
mikhail-ekzi edd43d6042 Fix PatchClass parsing for CID_SHIFT1 snapshots 2026-09-08 09:13:29 +02:00
81 changed files with 3103 additions and 568 deletions

No files matched your search

+85 -16
View File
@@ -1,7 +1,7 @@
name: ci
env:
R2V: 6.2.2
R2V: 6.2.4
on:
push:
@@ -28,13 +28,47 @@ jobs:
run: r2r test/db/cmd
- name: Radare Extras Testing
run: r2r test/db/extras
- name: Package Linux build
run: make -C dist/linux
- name: Upload Linux package
- name: Package r2pm binary
run: make bindist
- name: Verify r2pm binary
run: |
unzip -l r2flutter-${{ env.R2V }}-linux-x86-64.zip
unzip -l r2flutter-${{ env.R2V }}-linux-x86-64.zip | grep -q 'bin/r2flutter$'
unzip -l r2flutter-${{ env.R2V }}-linux-x86-64.zip | grep -q 'plugins/core_flutter.so$'
- name: Upload r2pm binary
uses: actions/upload-artifact@v7
with:
name: r2flutter-linux-x86_64
path: dist/linux/r2flutter-linux-x86_64.tar.gz
name: bindist-linux-x86-64
path: r2flutter-*.zip
if-no-files-found: error
- name: Package Debian build
run: make -C dist/debian
- name: Verify Debian package
shell: bash
run: |
shopt -s nullglob
packages=(dist/debian/r2flutter_*_amd64.deb)
test "${#packages[@]}" -eq 1
package="${packages[0]}"
version="$(./configure -qV)"
test "$(dpkg-deb --field "${package}" Package)" = r2flutter
test "$(dpkg-deb --field "${package}" Version)" = "${version}"
test "$(dpkg-deb --field "${package}" Architecture)" = amd64
test "$(dpkg-deb --field "${package}" Depends)" = radare2
contents="$(dpkg-deb --contents "${package}")"
printf '%s\n' "${contents}"
grep -E '^-.+ root/root .+ \./usr/local/bin/r2flutter$' <<< "${contents}"
plugin=".$(r2 -H R2_LIBR_PLUGINS)/core_flutter.so"
grep -Fq "${plugin}" <<< "${contents}"
make user-uninstall
sudo dpkg --force-depends --install "${package}"
test "$(r2flutter -V)" = "r2flutter ${version}"
test "$(r2 -q -c 'r2flutter -V' --)" = "r2flutter ${version}"
- name: Upload Debian package
uses: actions/upload-artifact@v7
with:
name: r2flutter-debian-amd64
path: dist/debian/r2flutter_*_amd64.deb
if-no-files-found: error
meson-linux24:
@@ -73,13 +107,40 @@ jobs:
run: r2r test/db/cmd
- name: Radare Extras Testing
run: r2r test/db/extras
- name: Package macOS build
run: make -C dist/macos
- name: Upload macOS package
- name: Package r2pm binary
run: make bindist
- name: Verify r2pm binary
run: |
unzip -l r2flutter-${{ env.R2V }}-darwin-arm-64.zip
unzip -l r2flutter-${{ env.R2V }}-darwin-arm-64.zip | grep -q 'bin/r2flutter$'
unzip -l r2flutter-${{ env.R2V }}-darwin-arm-64.zip | grep -q 'plugins/core_flutter.dylib$'
- name: Upload r2pm binary
uses: actions/upload-artifact@v7
with:
name: r2flutter-macos
path: dist/macos/r2flutter-macos.tar.gz
name: bindist-darwin-arm-64
path: r2flutter-*.zip
if-no-files-found: error
build-linux-arm:
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v7
- name: Installing radare2 ${{ env.R2V }}
uses: radareorg/github-actions@v3
with:
version: ${{ env.R2V }}
from-git: false
- name: Building r2flutter
run: make && make user-install
- name: Basic Testing
run: make test
- name: Package r2pm binary
run: make bindist
- name: Upload r2pm binary
uses: actions/upload-artifact@v7
with:
name: bindist-linux-arm-64
path: r2flutter-*.zip
if-no-files-found: error
build-windows:
@@ -104,11 +165,19 @@ jobs:
- name: Build and package r2flutter
shell: pwsh
run: ./dist/windows/build.ps1
- name: Verify Windows package
shell: pwsh
run: |
Expand-Archive -Path r2flutter-$env:R2V-windows-x86-64.zip -DestinationPath check-zip -Force
Get-ChildItem -Recurse check-zip | Select-Object -ExpandProperty FullName
$root = 'check-zip'
if (-not (Test-Path "$root/bin/r2flutter.exe")) { throw 'missing r2flutter.exe' }
if (-not (Test-Path "$root/plugins/core_flutter.dll")) { throw 'missing core_flutter.dll' }
- name: Upload Windows package
uses: actions/upload-artifact@v7
with:
name: r2flutter-windows-x86_64
path: dist/windows/r2flutter-windows-x86_64.zip
name: bindist-windows-x86-64
path: r2flutter-*.zip
if-no-files-found: error
r2-xps:
@@ -141,6 +210,7 @@ jobs:
- build-linux24
- meson-linux24
- build-macos
- build-linux-arm
- build-windows
- r2-xps
runs-on: ubuntu-24.04
@@ -198,6 +268,5 @@ jobs:
body_path: RELEASE_NOTES.md
generate_release_notes: false
files: |
release-artifacts/r2flutter-linux-x86_64/r2flutter-linux-x86_64.tar.gz
release-artifacts/r2flutter-macos/r2flutter-macos.tar.gz
release-artifacts/r2flutter-windows-x86_64/r2flutter-windows-x86_64.zip
release-artifacts/r2flutter-debian-amd64/r2flutter_*_amd64.deb
release-artifacts/bindist-*/r2flutter-*.zip
+1
View File
@@ -6,3 +6,4 @@ bin
*.so
*.dylib
*.swp
/r2flutter-*.zip
+26 -2
View File
@@ -9,7 +9,7 @@ LDFLAGS += $(R2_LDFLAGS)
LDLIBS += $(R2_LIBS)
DEPFLAGS = -MMD -MP
R2R_JOBS ?= 1
R2R_TIMEOUT ?= 30
R2R_TIMEOUT ?= 60
R2_LIBR_PLUGINS=$(shell r2 -H R2_LIBR_PLUGINS 2> /dev/null)
R2_LIBEXT=$(shell r2 -H R2_LIBEXT 2> /dev/null)
-include config.mk
@@ -73,6 +73,30 @@ user-install user-uninstall:
$(MAKE) -C src/r2
$(MAKE) -C src/r2 $@
# Binary package for r2pm -bi: bin/ and plugins/ for this r2 version and platform
# r2 <= 6.2.2 lacks r2pm -H R2PM_TRIPLET, fallback to the host asm.* defaults
PKG_TRIPLET := $(or $(shell r2pm -H R2PM_TRIPLET 2> /dev/null),$(shell r2 -N -qc '?e `e asm.os`-`e asm.arch`-`e asm.bits`' -- 2> /dev/null))
BINDIST_ZIP = r2flutter-$(shell r2 -qv)-$(PKG_TRIPLET).zip
BINDIST_DIR = $(BUILD_DIR)/bindist
BINDIST_FILES = $(BINDIST_DIR)/bin/r2flutter $(BINDIST_DIR)/plugins/core_flutter.$(R2_LIBEXT)
STRIP ?= strip
bindist: $(BIN_FILE)
$(MAKE) $(STATIC_LIB)
$(MAKE) -C src/r2
rm -rf $(BINDIST_DIR) $(BINDIST_ZIP)
mkdir -p $(BINDIST_DIR)/bin $(BINDIST_DIR)/plugins
cp -f $(BIN_FILE) $(BINDIST_DIR)/bin/
cp -f src/r2/core_flutter.$(R2_LIBEXT) $(BINDIST_DIR)/plugins/
cp -f dist/README.md $(BINDIST_DIR)/
ifeq ($(R2_LIBEXT),dylib)
$(STRIP) -x $(BINDIST_FILES)
codesign -f -s - $(BINDIST_FILES)
else
$(STRIP) --strip-unneeded $(BINDIST_FILES)
endif
cd $(BINDIST_DIR) && zip -r $(CURDIR)/$(BINDIST_ZIP) README.md bin plugins
install: uninstall
mkdir -p "$(DESTDIR)$(PREFIX)/bin"
cp -f bin/r2flutter "$(DESTDIR)$(PREFIX)/bin/r2flutter"
@@ -105,6 +129,6 @@ test: $(BIN_FILE)
@echo "Running custom testsuite"
@python3 scripts/run_tests.py
.PHONY: all clean test test-r2r r2 plugin user-install user-uninstall fmt indent format
.PHONY: all clean test test-r2r r2 plugin user-install user-uninstall fmt indent format bindist
-include $(DEP_FILES)
Vendored
+5 -5
View File
@@ -127,12 +127,12 @@ done
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
: ${INSTALL_MAN:=${INSTALL} -m 444}
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
PKGNAME='r2flutter' ; VERSION='0.3.2' ; VERSION_MAJOR=0; VERSION_MINOR=3; VERSION_PATCH=2; VERSION_NUMBER=00302; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
PKGNAME='r2flutter' ; VERSION='0.6.0' ; VERSION_MAJOR=0; VERSION_MINOR=6; VERSION_PATCH=0; VERSION_NUMBER=00600; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
}
show_usage() {
cat <<EOF2
'configure' configures r2flutter-0.3.2 to adapt to many kinds of systems.
'configure' configures r2flutter-0.6.0 to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
@@ -214,10 +214,10 @@ ocho() {
show_version() {
if [ "$QUIET" = 1 ]; then
echo "0.3.2"
echo "0.6.0"
exit 0
fi
echo "r2flutter-0.3.2 configuration script done with acr v2.2.8.
echo "r2flutter-0.6.0 configuration script done with acr v2.2.8.
The 'Free Software Foundation' message is only for autodetection.
Originally written by pancake <nopcode.org>."
exit 0
@@ -246,7 +246,7 @@ case $flag in
show_version ; ;;
-r|--r|--report)
echo "PKGNAME: r2flutter"
echo "VERSION: 0.3.2"
echo "VERSION: 0.6.0"
echo "AUTHOR: pancake"
echo "EMAIL: [email protected]"
echo "LANGS: c"
+1 -1
View File
@@ -1,5 +1,5 @@
PKGNAME r2flutter
VERSION 0.3.2
VERSION 0.6.0
CONTACT pancake ; [email protected]
LANG_C!
+36
View File
@@ -0,0 +1,36 @@
# r2flutter binary release
This package contains:
* `bin/r2flutter` — the standalone command line tool
* `plugins/core_flutter.{so,dylib,dll}` — the radare2 core plugin
## Installing
Copy the tool anywhere in your `$PATH` and drop the plugin into the radare2
plugin directory reported by r2:
```sh
r2 -H R2_USER_PLUGINS # per user, no root needed
r2 -H R2_LIBR_PLUGINS # system wide
```
For example:
```sh
mkdir -p "$(r2 -H R2_USER_PLUGINS)"
cp plugins/core_flutter.* "$(r2 -H R2_USER_PLUGINS)"
cp bin/r2flutter /usr/local/bin
```
On Windows the plugin directory is usually `%HOMEPATH%\.local\share\radare2\plugins`.
## Checking the installation
```sh
r2 -qc 'Lc~r2flutter' --
r2flutter -V
```
The plugin must match the radare2 version it was built against, otherwise r2
refuses to load it.
+13
View File
@@ -0,0 +1,13 @@
PACKAGE=r2flutter
VERSION?=$(shell ../../configure -qV)
DEPENDS=radare2
SECTION=user/shell
PRIORITY=optional
MAINTAINER=pancake <[email protected]>
# arch
UNAMEM=$(shell uname -m)
ifeq ($(UNAMEM),x86_64)
ARCH?=amd64
else
ARCH?=arm64
endif
+30
View File
@@ -0,0 +1,30 @@
include ./CONFIG
PWD=$(shell pwd)
all: deb
deb:
$(MAKE) root
$(MAKE) build
root:
rm -rf root
$(MAKE) -C ../.. install DESTDIR=$(PWD)/root
build:
mkdir -p root/DEBIAN
echo "Package: $(PACKAGE)" > root/DEBIAN/control
echo "Version: $(VERSION)" >> root/DEBIAN/control
echo "Section: $(SECTION)" >> root/DEBIAN/control
echo "Priority: $(PRIORITY)" >> root/DEBIAN/control
echo "Architecture: $(ARCH)" >> root/DEBIAN/control
echo "Depends: $(DEPENDS)" >> root/DEBIAN/control
echo "Maintainer: $(MAINTAINER)" >> root/DEBIAN/control
echo "Description: r2flutter plugin for radare2" >> root/DEBIAN/control
dpkg-deb --root-owner-group --build root $(PACKAGE)_$(VERSION)_$(ARCH).deb
clean:
rm -rf root *.deb
.PHONY: all deb root build clean
-14
View File
@@ -1,14 +0,0 @@
ROOT := $(CURDIR)/r2flutter-linux-x86_64
ARCHIVE := $(CURDIR)/r2flutter-linux-x86_64.tar.gz
all:
rm -rf $(ROOT) $(ARCHIVE)
mkdir -p $(ROOT)/bin $(ROOT)/plugins
cp ../../bin/r2flutter $(ROOT)/bin/
cp ../../src/r2/core_flutter.so $(ROOT)/plugins/
tar -C $(CURDIR) -czf $(ARCHIVE) r2flutter-linux-x86_64
clean:
rm -rf $(ROOT) $(ARCHIVE)
.PHONY: all clean
-14
View File
@@ -1,14 +0,0 @@
ROOT := $(CURDIR)/r2flutter-macos
ARCHIVE := $(CURDIR)/r2flutter-macos.tar.gz
all:
rm -rf $(ROOT) $(ARCHIVE)
mkdir -p $(ROOT)/bin $(ROOT)/plugins
cp ../../bin/r2flutter $(ROOT)/bin/
cp ../../src/r2/core_flutter.dylib $(ROOT)/plugins/
tar -C $(CURDIR) -czf $(ARCHIVE) r2flutter-macos
clean:
rm -rf $(ROOT) $(ARCHIVE)
.PHONY: all clean
+8 -5
View File
@@ -3,10 +3,13 @@ $ErrorActionPreference = 'Stop'
meson setup build-windows --buildtype=release
meson compile -C build-windows
$root = 'dist/windows/r2flutter-windows-x86_64'
$archive = 'dist/windows/r2flutter-windows-x86_64.zip'
$r2v = if ($env:R2V) { $env:R2V } else { (r2 -qv).Trim() }
$root = 'build-windows/bindist'
$archive = "r2flutter-$r2v-windows-x86-64.zip"
Remove-Item -Recurse -Force $root -ErrorAction SilentlyContinue
Remove-Item -Force $archive -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force $root | Out-Null
Copy-Item build-windows/r2flutter.exe $root/
Compress-Archive -Path $root -DestinationPath $archive -Force
New-Item -ItemType Directory -Force $root/bin,$root/plugins | Out-Null
Copy-Item build-windows/r2flutter.exe $root/bin/
Copy-Item build-windows/core_flutter.dll $root/plugins/
Copy-Item dist/README.md $root/
Compress-Archive -Path $root/* -DestinationPath $archive -Force
+501
View File
@@ -1566,3 +1566,504 @@ prefix. The ABI number can still match while host structures cross library
instances, producing hangs or crashes in parser-heavy commands. The Darwin
plugin target therefore leaves radare2 symbols unresolved; Linux continues to
link the libraries reported by `r2 -H R2_LIBS`.
## Dart 3.13 Serializes Base Objects In Early Clusters
With the VM snapshot gone, Dart 3.13 no longer registers the VM singletons
(`empty_object_pool`, `empty_descriptors`, `empty_var_descriptors`, the
preallocated errors, ...) as base objects. `Serializer::CreateEarlyClusters`
writes them as ordinary clusters at the start of the combined snapshot, so a
real 3.13 app reports only a handful of base objects and its first clusters are
one-object Mint, ImmutableArray, ObjectPool, PcDescriptors, CompressedStackMaps
and LocalVarDescriptors clusters. The tiny synthetic fixtures never exercised
this; the first real 3.13 app (an iOS AuthPass build) desynced at cluster 5 and
left the global ObjectPool (cluster 1121) `not_parsed`, so `-p` reported
"PP not resolved".
Three cluster types gained serializers in 3.13 and had no CID kind here:
- `LocalVarDescriptors` (always `CompressedStackMaps + 1`): alloc is a count
plus one entry count per object (the same shape as the 3.13 Closure alloc);
fill is the entry count, one name ref per entry, then per entry four
`Read<int32_t>` values (index_kind and three token positions) and one
`Read<int64_t>` scope id. It is not an inline-bytes class, so widening the
PcDescriptors..CompressedStackMaps RO-data window would be wrong.
- `ApiError` (`LanguageError - 1`): fixed-size alloc, fill is one ref.
- `UnwindError` (`UnhandledException + 1`): fixed-size alloc, fill is one ref
plus a bool.
Those offsets hold for every class_id.h from 2.10 to 3.13, so the kinds were
added to all CID tables. Older serializers never emit these clusters.
The early empty ObjectPool also means "the first ObjectPool cluster" is no
longer the global pool. Pool walkers must skip zero-length pools instead of
stopping at the first pool they see.
## -AAA Scaling On Large Snapshots
A 37,863-function Dart 3.13 iOS app took 19 minutes in `r2flutter -AAA`; three
independent costs grew with the snapshot size. The fixes below brought it to
36 seconds with byte-identical flags, comments, xrefs, functions and
signatures.
- `read_mem` kept a single 1 MB window. `modern_load_rodata_strings`
alternates between a cluster alloc stream and the RO data image megabytes
away, so every string refilled the window twice (1 MB `read` plus the
`0xff` fill `r_io_bank_read_at` does first). The cache now keeps four
windows with LRU eviction. It also lives behind a pointer: `DartCtx` is
copied by value (`flutter_model_load`, `dart_recovery_model_load`), and the
old inline address fields went stale when a copy refilled the shared buffer.
A failed refill now drops the window, because the failed read has already
overwritten its buffer. `-f` went from 12.4s to 0.5s.
- `afs` stores a prototype through `r_anal_save_parsed_type`, which calls
`r_anal_remove_parsed_type` for each type the parsed C declares. For an
existing name that sorts and scans the whole type database, although
`r_type_del` has already removed every key of a function type. Names repeat
a lot: anonymous closures, and names the C parser cuts at `:`
(`...dyn:call` is stored as the type `call`). The signature pass now parses
the prototype with `r_anal_cparse` and `r_type_del`s those names first, so
`afs` returns early.
- With `anal.trycatch` enabled (the radare2 6.2.2 default) every `af` walks all
flags twice looking for `try.<addr>.catch|filter`. After -AAA creates its
flags that is O(flags) per function. r2flutter disables the option around
its `af` loops when no `try.` flag exists, which cannot change the result.
Two existing behaviours surfaced while checking equivalence and are kept as
they are: a second function with an already used name cannot be renamed by
`afs`, so it keeps no signature while the type of the first one is replaced;
and prototypes whose name contains `:` are parsed as a label, giving them a
shortened type name and a garbled return type.
## PP-slot comments: resolve inline and add xrefs
Task: after `r2flutter -AAA`, the disassembler showed many bare
`dart: PP slot +0x..` comments. Those slots resolve fine with `r2flutter -O
pp+0x..` by hand, so the analysis should inline what the slot holds (and add a
real xref) instead of leaving a hacky offset.
Reproduction (`test/bins/ios/.../App`, Dart 3.13, cws=8): `r2flutter -AAA` then
`CC*`. Before: string slots were inlined, but tens of thousands of slots stayed
as bare `dart: PP slot +0x..`. Decoding a sample with `-O` showed ~23% were
`code`/`function` refs (navigable!), the rest `canonical_set`/`instance`/
`type_arguments`/`array`/`native_function`/..., and ~1% strings whose bytes are
unrecoverable (`complete=false`, which `-O` cannot show either).
Root cause: `flutter_process_pp_load` only consulted the string-only
`pp_strings` map, so any non-string slot fell through to the bare comment, even
though the `-O` decode engine (`modern_resolve_pool_entry`) resolves every kind.
Fix: the new `modern_collect_direct_pool_refs` walks the pool once and reports
each entry's `{kind, name, cid, code_index, value_addr}`. The analysis builds a
pp_off->ref map plus a `code_index -> entrypoint` map from the instruction
table, then:
- string slot: inline the value (unchanged),
- function/code slot: comment with the resolved name and add an xref to the
entrypoint (CALL for `blr`, DATA otherwise),
- any other slot: label it with its kind so no slot is left as a bare offset.
Tested in `test/db/cmd/pp-slot-resolve-ios` against the committed Runner and
AuthPass App binaries.
## PP-slot comments: fix the mis-identification of loaded pool values
With slots now resolved, the "maybe PP is not properly identified" note turned
out to be a real register-tracking bug. The tracker set `has_pp_off` on the
*destination* of a pool load, so a later `[dst, field]` deref was read as
another pool slot. The classic case: `ldr x30,[x27,0x18]` (loads a Code object)
then `ldur x30,[x30,7]` (extracts the entry point) produced a bogus
`PP slot +0x1f` (0x18+7), and the following `blr x30` reported
`indirect call via PP+0x1f`. Fixes:
- a loaded value is an object, not a PP pointer: `pp_load` tags the dest with
`has_pp_slot`/`pp_slot` (the slot it came from), never `has_pp_off`;
- `flutter_process_pp_slot_deref` propagates that taint across the Code
entry-point deref so the `blr` names the real slot (0x18) and can xref it;
- a hard invariant guard: valid slots live at `(index+2)*word_size` with
`modern_target_word_size()==8`, so any computed `pp_off & 7` is a
tagged-object field/unbox deref, not a pool access, and is rejected outright.
Result (task AuthPass binary, Dart 3.13): bare PP slots 72900 -> 1144 (the
residual are all word-aligned `complete=false` strings `-O` cannot resolve
either), bare indirect calls 1178 -> 1, ~150 misaligned `+0x..7` bogus comments
-> 0, and 64439 slots now carry a kind/name plus xrefs. Verified on iOS (Dart
3.13/3.2.5, cws=8) and Android (w0rdle, Dart 2.18, cws=4): 0 misaligned on both.
## Expose the ObjectPool as r2's global pointer (anal.gp) in r2flutter-A
x27 (PP) is the only Dart reserved register with a *static* address: the
ObjectPool lives in the snapshot, so we know its base. `r2flutter -p -r`
already emitted `e anal.gp=<base>` / `dr x27=<base>` / `e anal.roregs=...`, but
the analysis command never set them, and the `-R` script had a dead
`dr x27=\`e anal.gp\`` that depended on an unset value. `r2flutter -A` (every
depth) now calls `r2flutter_setup_pp_gp`, which seeds `anal.gp` with the pool
base, `anal.gpseed=x27`, `anal.roregs=x27,gp,zero` and an `f PP` flag, so plain
r2 analysis/ESIL resolves `[x27, off]` pool loads consistently.
Gotcha worth remembering: `dart_resolve_pp_info` populates the context read
cache (`ctx->rmem`) and can leave a stale layout pointer. `dart_app_new_from_core`
copies the `DartCtx` by value (`memcpy`), so resolving on the live session
context and then running the analysis double-freed that cache (SIGABRT after
"Loaded N functions"). The setup resolves on a shallow copy with its own
`rmem`/`layout` and frees only what it allocated, leaving the session context
pristine. x22 (NULL_REG) and x26 (THR) are runtime pointers with no static
address, so they are documented/annotated, never seeded as anal.gp.
## Annotate the NULL_REG (x22) null/true/false idioms
x22 is Dart AOT's `NULL_REG`, caching `Object::null()` program-wide (a sibling
of PP, not part of it). The VM lays null/true/false out as adjacent heap
objects (`runtime/vm/pointer_tagging.h`): `true = null + 4*word_size`, `false =
null + 6*word_size`. On arm64 AOT the object-alignment word is the 8-byte
target word regardless of pointer compression, so the offsets are a constant
0x20 / 0x30 on every Dart version - verified on cws=8 (AuthPass, Dart 3.13/3.2.5)
and cws=4 (w0rdle, Dart 2.18). The `-AAA` scan now annotates:
- `add d, x22, #0x20` -> `dart: true`, `#0x30` -> `dart: false`,
- `mov d, x22` -> `dart: null`,
- `cmp r, x22` -> `dart: compare with null`.
This is exactly the primitive the FatalSec talk's Frida bypass keys on
(`add x0, x22, #0x20` = "return true" from the certificate-pinning wrapper).
Verified count on AuthPass: ~6k true, ~7k false, ~31k null, ~23k null-compares.
x26 (THR, the thread register with a large fixed-offset table of runtime stubs)
is the natural next target but is version-specific and left as a follow-up.
## Apply data-image string references so axt resolves pool strings
A string loaded only through a const data structure (e.g. a `Uri` or a list of
endpoints) is never loaded by a `ldr [x27, off]` in code, so the -AAA scan,
which only walks disassembled functions, created no xref for it. `axt
0x<string>` came back empty even though the string is clearly used. Example
(an Android app): `https://pss.aakredit.in/` at 0x76a97 is referenced from a
const object at 0x13a945 in `.rodata`; the scan never visits `.rodata`.
The reference was already recoverable - `r2flutter -z`/`-xz -r` lists each
reliable ObjectPool string with its reference sites (`DartStringRef.source_addr`,
including data-image addresses) and emits `ax <string> <source>` - but only as a
script that nothing applied, and -AAA never ran it. -AAA now calls
`dart_pool_apply_xrefs`, which walks `dart_pool_extract_pool_strings` and sets a
real STRN xref from every `source_addr` to the string, so `axt` resolves
pool-referenced strings that no instruction loads directly (4195 such xrefs on
that app).
Gotcha: `-xz` resolves to the strings action (`z`), not xrefs (`x`) - the `ax`
lines come from `dart_pool_strings.c` (string references), not
`dart_pool_extract_xrefs` (which only yields metadata refs with no source
address). The apply runs on a shallow DartCtx copy with its own read cache for
the same reason as `r2flutter_setup_pp_gp`: the scan has already mutated
app->dctx, and extraction needs the pristine state the standalone command sees.
## String dump config (`r2flutter.str.*`)
`r2flutter.str.limit`, `.minlen`, `.maxlen` and `.filter` replace the old
hardcoded `DART_STRING_SCAN_LIMIT` (50000). The defaults are unlimited/empty:
no test sample reaches 50k carved strings (mafia ~41k in 0.7s), and the carved
regions are already capped by `DART_SNAPSHOT_SCAN_MAX`/`DART_DATA_IMAGE_SCAN_MAX`.
minlen/maxlen/filter only filter what `-z`/`-zz` print, because the carved list
also feeds enum recovery and string-ref population. `str.limit` caps printed
matches and only stops the `-zz` carving early (`ctx->str_scan_limit`) when no
filter is set; otherwise the scan would stop before reaching the matches.
Careful: `r_regex_check` returns `r_regex_exec` as-is, i.e. **false on match**;
compare `r_regex_exec (rx, s, 0, NULL, 0) == 0` explicitly.
## x86-64 Dart AOT support in the register scan
A Flutter app built for Android x86_64 ships an ELF with `e_machine = x86-64`,
and its Dart AOT code is x64, not arm64. The register-tracking scan was
arm64-only, so on x64 it found 0 PP refs: `axt` on a string showed only the
data-image ref applied by -AA, never the code that loads it.
The x64 Dart ABI differs: PP is `r15` (not x27), THR is `r14`, there is no
NULL_REG (the x22 true/false/null trick is arm64-only), r2 types a memory
`mov` as MOV rather than LOAD/STORE, and - the subtle part - `r15` carries the
heap tag, so a `[r15, off]` instruction offset is one less than the
collector/arm64 slot offset (`sr->source_addr = pp_base + pp_off` uses the
collector offset). Changes:
- `flutter_reg_index` maps x64 register names; `flutter_reg_is_pp` adds r15.
- the mem-operand parser accepts `[r15 + off]` alongside `[x27, off]`.
- x64 `mov reg,[mem]` / `mov [mem],reg` are reclassified to LOAD/STORE via an
effective op type so the pool-load logic runs.
- the `(pp_off & 7)` alignment guard is dropped: it assumed arm64's even PP
base and rejected x64's tagged-base odd offsets; the has_pp_slot fix already
prevents the field-deref it guarded against.
- every pool load emits a code->pool-slot xref (pp_base + off), the "link code
to the PP table" that was missing on both arches.
- on x64 the heap tag (+1) is added back to get the canonical slot offset, so
the code xref lands on the same slot the string ref targets, pool strings
resolve inline, and a real code->string xref is emitted.
- `anal.gpseed`/`anal.roregs` are seeded with r15 on x64, x27 on arm64.
Result on an Android x86_64 app: 0 -> 36467 PP refs, and `axt 0x76a97` shows
`method.DioManager.initParams ... mov rax, [r15 + str.https:__pss.aakredit.in_]`
with the value inlined. arm64 is unchanged (27388 PP refs on w0rdle, 0
misaligned). Not yet handled: the x64 ObjectPool *slot* decoder (`-O pp+off`)
still misreads compressed pool pointers, so a slot that the collector did not
already resolve stays a bare offset; and there is no committed x86_64 test
fixture.
## Dart 2.19 Type fill must not consume the legacy combined byte
The Flutter 3.7.12/Dart 2.19.0 snapshot hash
`adb4292f3ec25074ca70abcd2d5c7251` exposed a one-byte fill-stream drift:
`r2flutter -HHH` stopped after the `TypeArguments` cluster and reported the
later ObjectPool as `fill_not_parsed`. Consequently `-AAA` could not build the
synthetic PP image or apply ObjectPool string xrefs; `axt 0x31903` for
`https://www.game250522linecfg.xyz` was empty.
The cause was treating all Dart 2.x `Type::ReadFill` records alike. Through
2.18 their three references are followed by `ReadUnsigned(type_class_id)` and
a one-byte combined nullability/type-state field. Dart 2.19 replaces that pair
with one `ReadUnsigned(flags)`. Consuming the obsolete byte desynchronizes the
rest of the fill stream. Keep the old rule only before 2.19; with the corrected
rule the ObjectPool reaches cluster 652, `-p` reconstructs 44955 entries, and
`r2flutter -AAA` applies 11560 graph xrefs, including an `axt` result for
0x31903.
## Code xrefs need discarded instructions and correctly shifted PP offsets
The Dart 2.19 sample above has 29622 instruction-table entries, but only 7545
retained `Code` objects. `first_entry_with_code=22077` separates instructions
whose `Code` metadata was discarded from entries with retained metadata; it
does not separate non-executable stubs from application code. The VM writer
in `runtime/vm/app_snapshot.cc` orders discarded Code objects first. Both URL
loaders are in that prefix (IT indices 14623 and 15109).
An unlimited instruction-table extraction must use the table header's length,
not the clustered header's retained Code count. `-AAA` must collect all table
entrypoints in addition to named methods so these functions get basic blocks
and their PP loads are scanned. `has_code` still controls Code-index metadata
lookups; it must not decide whether instructions can be analyzed.
ARM64 decoders can return an already shifted `RArchValue.imm` for
`add x17, x27, 0x46, lsl 12`. Applying the text's shift to that value again
produces `0x46000000`, breaking the subsequent pool lookup. Read the unshifted
immediate from the instruction text and apply the shift exactly once.
Verified with `/tmp/mal/libapp.so` (identical to `libapp.so.noxrefs`):
- `0x85b028` in `fcn.0085afb0` loads `PP+0x46200` and now has a direct string
xref to `0x73986` (`https://reg.gptreg0706.xyz`).
- `0x836f98` in `fcn.00836f4c` loads `PP+0x4e6c8` and now has a direct string
xref to `0x31903` (`https://www.game250522linecfg.xyz`).
The unaligned `0x20022d` and `0x2086f5` sources are synthetic pool slots in
the serialized snapshot address range, not executable use sites. `-AA` keeps
those pool links; `-AAA` adds the instruction-to-string links. Regression tests
cover a cached discarded-Code table on Android, and real shifted PP loads on
Android w0rdle and iOS Runner without depending on the private samples.
## Dart 2.19 class metadata uses the modern fill walker
`-c` printed ~280 `size=0` classes for a Dart 2.19 Android sample because
`modern_can_extract_classes` only accepted `OBJECT_HEADER` (3.4+) snapshots.
The legacy class parser then failed on the first (unified `String`) cluster
and the string heuristic took over. The modern walker already handles
`CID_SHIFT1` (2.14-3.3) for `-H`, pools and xrefs, and the Class fill layout
(13 refs: name=0, library=7, super_type=9) matches 2.19 product snapshots.
Gating on `modern_supported` recovers 6914 classes, 1515 fields and 7398
methods on that sample.
## Class methods resolve entry points from InstructionTable slots
`Function` fills only carry a code index; `DartMethodInfo.entry_point` was
never set, so every class method printed `0x00000000` on all versions. The
index is the raw InstructionTable slot, not the `first_entry_with_code`
relative `DartInstructionTableEntry.code_index`. Slots below
`first_entry_with_code` belong to functions whose Code object was discarded
(`dwarf_stack_traces_mode`), but they still own real instructions, so they are
mapped too. On the 2.19 sample 22077 of 29622 slots are like that; `-f` used
to list only the 7545 Code-backed ones and now also gets the 4614 named
methods in the discarded range through `dart_app_merge_class_methods`.
InstructionTable names stay authoritative there: `dedup_instructions` makes
several methods share one body, so class-derived names only replace
placeholder (`func.*`, `method.fn_*`) names.
## Signed 64-bit varints use the 192 end-byte marker
`cs_read_tagged64` decoded the final varint byte as `raw - 64` instead of
`raw - 192` (`ReadStream::Read<T>` uses `kEndByteMarker`), adding
`128 << shift` to every Mint/Smi. Field offsets (`host_offset_or_field_id`)
came out as 128 + words, e.g. `_Closure._context` at `+0x428` instead of
`+0x28` on 64-bit, and the `SemanticsAction` const map key `tap` decoded as
129 instead of 1. `cs_read_tagged32` was already correct.
## ObjectPool instances can carry strings through their fields
`t/libapp_1.so` loads `PP+0x17200` at `0xfb4ae8`. The slot references
snapshot object 165628, a `Ubb` instance derived from `_Enum`; its string field
references object 33665 (`privilegedAccess`, payload `0xbcedf`). Blutter's
`pp.txt` confirms enum index 9 and the name at instance offset `0x10`.
A direct-String-only PP lookup consequently misses this use.
Analysis now collects direct strings and immediate string fields of pool
instances. `-AA` links the synthetic pool slot (`0x30a1b0` in this sample) to
the string, and `-AAA` links the loading instruction and adds a `contains
string` comment while retaining the `instance` label. Each slot can contain
multiple strings; they must not collapse to its first string field. This
analysis path stops at immediate fields rather than traversing metadata or
arbitrary object graphs.
Instance field counts include an eight-byte header expressed in compressed
words: two words on compressed Android snapshots, one on uncompressed iOS.
Using a fixed two-word header skips the enum name on iOS. The collector also
loads ROData strings for uncompressed snapshots and preserves VM base-object
strings. Regression tests use `Brightness.dark` in Android w0rdle and iOS
Runner to cover both layouts, pool xrefs, and instruction comments/xrefs.
PP resolution can initialize `ctx->layout` from a local stack buffer. Callers
that need to continue parsing after it returns must keep their own live
layout across resolution and free it afterward; otherwise the field-string
collector can silently miss all slots on either platform.
Instance fill offsets are indexed once per cluster while collecting strings.
Rescanning a cluster prefix for each PP slot makes large const collections
quadratic, even when only immediate fields are read.
## Reliable string extraction shares the PP instance-field collector
`-z` previously accepted only direct String ObjectPool entries, so it omitted
`privilegedAccess` even after analysis could recover its enum instance field.
Reliable extraction now uses the same direct-string and immediate-instance-field
collector as PP analysis. This also resolves uncompressed iOS ROData strings
and VM base-object strings through that collector.
Strings remain deduplicated by snapshot string reference. `-xz` distinguishes
`object_pool.entry` from `object_pool.instance_field`, recording the containing
pool entry and field index. Both reference kinds use the synthetic PP slot as
the xref source. The shared extraction makes the separate instance-field xref
pass redundant; `-AA` now applies the references from the extracted strings.
Regression cases cover the instance-only `AppLifecycleState.detached` name on
Android w0rdle and iOS Runner, plus a name (`dark`) reachable both directly and
through an instance to check that it is emitted once.
## Collection values propagate their strings into PP analysis
Android w0rdle `PP+0x5d0` and iOS Runner `PP+0x3d0` hold the ten
`PointerChange` enum instances. The value inspector decoded their names, but
the analysis collector rejected every collection before inspecting its
contents. The same restriction missed strings in map/set backing arrays.
The value collector now follows arrays, weak arrays, growable arrays, maps,
sets, and instances, while excluding Class/Function/type metadata. Map/set
storage adds an extra hop, so value traversal allows eight edges of depth
and at most 4096 reference visits per pool entry. Per-entry visited depths
stop cycles and allow revisiting a shared object reached by a shorter path.
Null references count toward the visit budget too.
Array and reference-object fill offsets are indexed once per cluster, as
instance offsets already were, to avoid repeatedly scanning array prefixes.
`-xz` marks strings reached through collections as `object_pool.collection`
and records their immediate leaf kind/index. `-AA` links their pool slots;
`-AAA` adds instruction xrefs and `contains string` comments while retaining
the collection's original kind. Regression fixtures cover both platforms and
cyclic arrays with shared elements behind mutable/const map and set storage.
## Field ObjectPool entries resolve their owner and name
W0rdle `PP+0x60` references Field object 52876 (`Platform.isAndroid`). The
field fill was decoded for class extraction but the PP resolver classified
Field by its generic allocation kind (`simple`) and retained no name/owner
references. iOS Runner `PP+0x120` similarly references
`Zone._current@4048458` (object 40563).
The shared resolver now records Field name/owner references while walking
fills and resolves owners through Class, Library, or bounded PatchClass
chains. Field labels use `Owner.name`, preserve private-name suffixes, and
apply the obfuscation map to both parts. Missing owners leave the field name
alone; missing names leave a `field` kind without a fabricated label. PP
inspection, cluster summaries, reference inspection, and analysis comments
share that resolution.
Uncompressed isolate field names are ROData strings. Loading those strings
in the shared resolver enables field labels on iOS as well as compressed
Android snapshots and replaces duplicate ROData loading in value graphs and
string collection. Regression fixtures cover both platforms, patched and
cyclic owners, missing names/owners, and deobfuscation.
## Direct Code pool references use Code allocation indices
ObjectPool resolution recognized Code objects but only assigned a target index
for Function references. Code-slot loads and indirect calls therefore had a
`code` annotation without a navigable instruction target.
The main Code allocation range has the same order as the Code-backed part of
the InstructionTable. Its zero-based index is `ref - cluster.start_ref`, which
matches `DartInstructionTableEntry.code_index`; the table extractor handles
`first_entry_with_code` when mapping that index to a payload address. Do not
reuse the serialized Function index here: that index is biased by one and
refers to the whole table. Deferred Code objects follow the main allocation
range but have no instructions in this loading unit, so they keep an unresolved
target. A discarded record in older Code clusters still occupies its ordinal.
On Android w0rdle, `PP+0x40` holds ref 33249 in the Code cluster starting at
22433, so it resolves to index 10816 and table address `0x3f1074`. Analysis now
adds a CALL xref from `blr x0` at `0x3f28cc`, preserving the PP association
through the Code entry-point load. `PP+0x48` resolves to the following index.
On iOS AuthPass, `PP+0x68` holds ref 168520 in the Code cluster starting at
132121, yielding index 36399 and table address `0x6d9620`. The synthetic
regression checks index zero, a discarded record, the following main record,
and an unresolved deferred record. These targets use the existing table
payload-address convention described above.
## Record inspection decodes the shape and field references
Record fills contain `ReadUnsigned (shape)` followed by one reference per
field. `RecordShape::NumFieldsBitField` in the VM is the low 16 bits; the upper
bits identify the registered array of named field names. Allocation records
separately store each Record's field count. Retain those counts and check each
fill against its own allocation instead of accepting only matching cluster
minimum, maximum, and total counts.
The value graph now decodes Record fields into the same bounded edges used by
other objects. JSON includes `shape`, `field_names_index`, `length`, and
`fields`; text output prints the shape, length, and child values. Labels remain
ordinal (`field_0`, etc.); the shape's named-field table index is preserved
rather than treated as a reference or used to invent names. Empty Records
report length zero. Cycles, depth limits, and the 128-child display limit use
the existing graph handling. An unreadable or inconsistent Record fill stays
`complete: false`.
In `t/libapp_1.so`, ref 146422 has shape 2 and fields referring to base object
996 and instance 164557; that instance exposes the string `DOUBLE_QUOTE`.
The public Android mafia fixture has the equivalent Record at ref 158051,
whose second field is an `XmlAttributeType` instance. Synthetic compressed and
uncompressed snapshots cover nested Records, named shapes, empty Records,
cycles, truncation, and a malformed field count. Existing iOS graph tests
continue to cover arrays, maps, and sets; those fixtures have no Record cluster.
## Standalone xrefs scan full instruction-table payloads
The `-x` ObjectPool-use scanner used to ignore entries without retained Code
metadata, stop after 4096 functions by default, and inspect at most 96
instructions per function. This missed real instructions in the discarded-Code
prefix and PP references late in a function or instruction table.
The scanner now visits every instruction-table entry with an address and scans
to the next distinct entry address. The last payload ends at the instructions
image size recorded in its header, checked against its IO mapping. Instruction
sizes must fit inside that range. Table extraction is unlimited even when
`-l` caps emitted xrefs, so an output limit cannot remove the boundary needed
for a scanned function. PP-use buckets use a hash lookup to keep the expanded
scan practical. Instruction addresses identify visited use sites directly,
avoiding collisions from the previous XOR of address and PP offset.
Android w0rdle now includes the string load at `0x1b675c`, instruction 389 of
IT entry 808 (`Base64Codec.normalize`), and the load at `0x3f4908` in entry
10906. iOS Runner includes `0x929d0`, instruction 107 of entry 2642
(`TextPainter.layout`), and `0xea070` in entry 4235 (`Layer.dispose`).
Regressions also mark the Android table entries as lacking Code metadata and
place matching PP loads in the last function and outside the image to check
coverage and bounds. This expands instruction coverage; operand decoding
continues to use the existing standalone scanner.
## Duplicate Dart method names need unique r2 flags and function names
Several functions can share a Dart name (e.g. many `Native._anon_closure`).
r2 flag and function names are unique, so `r_flag_set` on a repeated name
moves the flag to the later function. Older r2 left a stale per-address entry
behind, which let `af` still pick the moved `method.*` name; current r2 does
not, and `af` also prefers symbol-space flags such as Mach-O `sym.func.*`.
The first function keeps `method.<name>` and repeats get a `.0x<addr>` suffix,
computed once in app order and shared by the flags, the `afs` prototypes and
`dart_dumper_name_functions`, which renames analyzed functions after the `af`
pass. The signature `af` storm also disables `anal.vars`, `anal.calls` and
`anal.jmp.tbl` like `flutter_ensure_functions`; var recovery was about half
of its cost (AuthPass `-AAA` 47s -> 29s).
+5
View File
@@ -390,6 +390,11 @@ Config keys:
- `r2flutter.mapfile`: Flutter obfuscation map JSON path
- `r2flutter.namepool`: enable heuristic name-pool fallback
- `r2flutter.profile`: override Dart snapshot profile by 32-byte hash or Dart version
- `r2flutter.str.limit`: max number of strings printed by `-z`/`-zz` (default `0`, unlimited); without filters it also stops the `-zz` carving early
- `r2flutter.str.minlen`: skip printing strings shorter than N (default `0`)
- `r2flutter.str.maxlen`: skip printing strings longer than N (default `0`, unlimited)
- `r2flutter.str.filter`: only print strings matching this extended regex (default empty)
Plugin modifiers:
+3
View File
@@ -31,6 +31,7 @@ typedef enum {
DART_CID_PC_DESCRIPTORS,
DART_CID_CODE_SOURCE_MAP,
DART_CID_COMPRESSED_STACK_MAPS,
DART_CID_LOCAL_VAR_DESCRIPTORS,
DART_CID_EXCEPTION_HANDLERS,
DART_CID_CONTEXT,
DART_CID_CONTEXT_SCOPE,
@@ -43,8 +44,10 @@ typedef enum {
DART_CID_MEGAMORPHIC_CACHE,
DART_CID_SUBTYPE_TEST_CACHE,
DART_CID_LOADING_UNIT,
DART_CID_API_ERROR,
DART_CID_LANGUAGE_ERROR,
DART_CID_UNHANDLED_EXCEPTION,
DART_CID_UNWIND_ERROR,
DART_CID_INSTANCE,
DART_CID_LIBRARY_PREFIX,
DART_CID_TYPE_ARGUMENTS,
+5
View File
@@ -11,6 +11,11 @@ char *dart_dumper_dump_r2(DartApp *app);
char *dart_dumper_dump_funcs(DartApp *app, int fmt);
void dart_dumper_apply_to_core(DartApp *app, bool apply_signatures);
void dart_dumper_apply_signatures(DartApp *app);
void dart_dumper_name_functions(DartApp *app);
// Disable anal.trycatch while r2flutter runs many `af` commands, when no try.*
// flag exists for it to find. Returns the previous value to pass to the restore.
bool dart_core_trycatch_suspend(RCore *core);
void dart_core_trycatch_restore(RCore *core, bool prev);
#ifdef __cplusplus
}
+1
View File
@@ -203,6 +203,7 @@ char *dart_pool_dump_strings(DartCtx *ctx, int fmt);
char *dart_pool_dump_strings_fuzzy(DartCtx *ctx, int fmt);
void dart_string_list_free(RList *list);
char *dart_pool_dump_xrefs(DartCtx *ctx, int fmt);
int dart_pool_apply_xrefs(DartCtx *ctx);
char *dart_pool_dump_sbom(DartCtx *ctx, const char *input_path, int fmt);
// ============================================================================
+11 -4
View File
@@ -81,16 +81,23 @@ typedef struct {
int dump_fields;
int dump_strings;
bool dump_string_refs;
ut64 str_limit; // max strings to print (0 = unlimited)
ut64 str_scan_limit; // max strings to carve in the fuzzy scan (0 = unlimited)
int str_minlen; // skip printing strings shorter than this
int str_maxlen; // skip printing strings longer than this (0 = unlimited)
const char *str_filter; // only print strings matching this regex
const char *obf_map_path;
HtPP *obf_by_obfuscated;
bool obf_map_tried;
// Windowed read cache for read_mem, to avoid one r_io_read_at syscall per
// byte while decoding cluster streams (which read one byte at a time).
// Scoped to a single command invocation and released by dart_obf_fini.
ut8 *rmem_cache;
ut64 rmem_cache_addr;
int rmem_cache_len;
int rmem_cache_cap;
// Heap-allocated so that DartCtx copies share the windows together with
// their addresses.
struct dart_read_cache_t *rmem;
} DartCtx;
// Release a read_mem window cache (NULL is accepted).
void dart_read_cache_free(struct dart_read_cache_t *cache);
#endif
+3 -3
View File
@@ -1,9 +1,9 @@
#ifndef R2FLUTTER_VERSION_H
#define R2FLUTTER_VERSION_H
#define R2FLUTTER_VERSION "0.3.2"
#define R2FLUTTER_VERSION "0.6.0"
#define R2FLUTTER_VERSION_MAJOR 0
#define R2FLUTTER_VERSION_MINOR 3
#define R2FLUTTER_VERSION_PATCH 2
#define R2FLUTTER_VERSION_MINOR 6
#define R2FLUTTER_VERSION_PATCH 0
#endif
+46 -4
View File
@@ -1,18 +1,47 @@
project(
'r2flutter',
'c',
version : '0.3.2',
meson_version : '>=0.55.0',
version : '0.6.0',
meson_version : '>=0.56.0',
default_options : ['warning_level=2', 'werror=false']
)
cc = meson.get_compiler('c')
r2 = find_program('r2', required: true)
r2_cflags_res = run_command(r2, '-H', 'R2_CFLAGS', check: true)
r2_ldflags_res = run_command(r2, '-H', 'R2_LDFLAGS', check: true)
r2_libs_res = run_command(r2, '-H', 'R2_LIBS', check: true)
r2_plugdir_res = run_command(r2, '-H', 'R2_LIBR_PLUGINS', check: false)
r2_compile_args = r2_cflags_res.stdout().strip().split()
r2_link_args = r2_ldflags_res.stdout().strip().split() + r2_libs_res.stdout().strip().split()
r2_plugdir = r2_plugdir_res.stdout().strip()
if r2_plugdir == ''
r2_plugdir = join_paths(get_option('prefix'), get_option('libdir'), 'radare2', 'last')
endif
# r2 -H always reports gcc style flags, msvc needs its own spelling for them
if cc.get_argument_syntax() == 'msvc'
msvc_link_args = []
foreach flag : r2_link_args
if flag.startswith('-L')
msvc_link_args += '/LIBPATH:' + flag.substring(2)
elif flag.startswith('-l')
msvc_link_args += flag.substring(2) + '.lib'
else
msvc_link_args += flag
endif
endforeach
r2_link_args = msvc_link_args
# posix names like strdup are available, just noisy without this
r2_compile_args += ['-D_CRT_SECURE_NO_WARNINGS', '-D_CRT_NONSTDC_NO_DEPRECATE']
endif
r_core_dep = declare_dependency(
compile_args: r2_cflags_res.stdout().strip().split(),
link_args: r2_ldflags_res.stdout().strip().split() + r2_libs_res.stdout().strip().split(),
compile_args: r2_compile_args,
link_args: r2_link_args,
)
r2flutter_inc = include_directories('include')
@@ -61,4 +90,17 @@ r2flutter_cli = executable(
install: true,
)
# The radare2 core plugin, loaded by r2 as core_flutter.{so,dylib,dll}
core_flutter = shared_module(
'core_flutter',
'src/r2/core_flutter.c',
'src/r2/flutter_analysis.c',
name_prefix: '',
include_directories: r2flutter_inc,
link_with: r2flutter_static,
dependencies: r_core_dep,
install: true,
install_dir: r2_plugdir,
)
test('r2flutter-version', r2flutter_cli, args: ['-V'])
+26 -26
View File
@@ -5,32 +5,32 @@
"function_name_offsets": [24, 8]
},
"profiles": {
"2.10.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_INT32", "header_fields": 4, "typed_data_internal_base": 108, "typed_data_internal_limit": 150, "typed_data_stride": 3, "cids": {"ILLEGAL": 0, "CLASS": 4, "PATCH_CLASS": 5, "FUNCTION": 6, "CLOSURE_DATA": 7, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 77, "CODE": 16, "OBJECT_POOL": 20, "PC_DESCRIPTORS": 21, "CODE_SOURCE_MAP": 22, "COMPRESSED_STACK_MAPS": 23, "EXCEPTION_HANDLERS": 25, "CONTEXT": 26, "CONTEXT_SCOPE": 27, "SINGLE_TARGET_CACHE": 29, "UNLINKED_CALL": 30, "MONOMORPHIC_SMIABLE_CALL": 31, "CALL_SITE_DATA": 32, "ICDATA": 33, "MEGAMORPHIC_CACHE": 34, "SUBTYPE_TEST_CACHE": 35, "LOADING_UNIT": 36, "LANGUAGE_ERROR": 39, "UNHANDLED_EXCEPTION": 40, "INSTANCE": 42, "LIBRARY_PREFIX": 43, "TYPE_ARGUMENTS": 44, "TYPE": 46, "TYPE_REF": 47, "TYPE_PARAMETER": 48, "CLOSURE": 49, "MINT": 53, "DOUBLE": 54, "FLOAT32X4": 57, "INT32X4": 58, "FLOAT64X2": 59, "TYPED_DATA": 61, "EXTERNAL_TYPED_DATA": 62, "TYPED_DATA_VIEW": 63, "CAPABILITY": 66, "RECEIVE_PORT": 67, "SEND_PORT": 68, "STACK_TRACE": 69, "REGEXP": 70, "WEAK_PROPERTY": 71, "FUTURE_OR": 74, "USER_TAG": 75, "TRANSFERABLE_TYPED_DATA": 76, "ARRAY": 78, "IMMUTABLE_ARRAY": 79, "GROWABLE_OBJECT_ARRAY": 56, "STRING": 80, "ONE_BYTE_STRING": 81, "TWO_BYTE_STRING": 82, "NUM_PREDEFINED_CIDS": 156}},
"2.12.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_INT32", "header_fields": 5, "typed_data_internal_base": 100, "typed_data_internal_limit": 142, "typed_data_stride": 3, "cids": {"ILLEGAL": 0, "CLASS": 4, "PATCH_CLASS": 5, "FUNCTION": 6, "CLOSURE_DATA": 7, "FFI_TRAMPOLINE_DATA": 8, "FIELD": 9, "SCRIPT": 10, "LIBRARY": 11, "NAMESPACE": 12, "KERNEL_PROGRAM_INFO": 13, "WEAK_SERIALIZATION_REFERENCE": 74, "CODE": 14, "OBJECT_POOL": 17, "PC_DESCRIPTORS": 18, "CODE_SOURCE_MAP": 19, "COMPRESSED_STACK_MAPS": 20, "EXCEPTION_HANDLERS": 22, "CONTEXT": 23, "CONTEXT_SCOPE": 24, "SINGLE_TARGET_CACHE": 25, "UNLINKED_CALL": 26, "MONOMORPHIC_SMIABLE_CALL": 27, "CALL_SITE_DATA": 28, "ICDATA": 29, "MEGAMORPHIC_CACHE": 30, "SUBTYPE_TEST_CACHE": 31, "LOADING_UNIT": 32, "LANGUAGE_ERROR": 35, "UNHANDLED_EXCEPTION": 36, "INSTANCE": 38, "LIBRARY_PREFIX": 39, "TYPE_ARGUMENTS": 40, "TYPE": 42, "FUNCTION_TYPE": 43, "TYPE_REF": 44, "TYPE_PARAMETER": 45, "CLOSURE": 46, "MINT": 50, "DOUBLE": 51, "FLOAT32X4": 54, "INT32X4": 55, "FLOAT64X2": 56, "TYPED_DATA": 58, "EXTERNAL_TYPED_DATA": 59, "TYPED_DATA_VIEW": 60, "CAPABILITY": 63, "RECEIVE_PORT": 64, "SEND_PORT": 65, "STACK_TRACE": 66, "REGEXP": 67, "WEAK_PROPERTY": 68, "FUTURE_OR": 71, "USER_TAG": 72, "TRANSFERABLE_TYPED_DATA": 73, "ARRAY": 75, "IMMUTABLE_ARRAY": 76, "GROWABLE_OBJECT_ARRAY": 53, "STRING": 77, "ONE_BYTE_STRING": 78, "TWO_BYTE_STRING": 79, "NUM_PREDEFINED_CIDS": 148}},
"2.13.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_INT32", "header_fields": 5, "typed_data_internal_base": 100, "typed_data_internal_limit": 142, "typed_data_stride": 3, "cids": {"ILLEGAL": 0, "CLASS": 4, "PATCH_CLASS": 5, "FUNCTION": 6, "CLOSURE_DATA": 7, "FFI_TRAMPOLINE_DATA": 8, "FIELD": 9, "SCRIPT": 10, "LIBRARY": 11, "NAMESPACE": 12, "KERNEL_PROGRAM_INFO": 13, "WEAK_SERIALIZATION_REFERENCE": 14, "CODE": 15, "OBJECT_POOL": 18, "PC_DESCRIPTORS": 19, "CODE_SOURCE_MAP": 20, "COMPRESSED_STACK_MAPS": 21, "EXCEPTION_HANDLERS": 23, "CONTEXT": 24, "CONTEXT_SCOPE": 25, "SINGLE_TARGET_CACHE": 26, "UNLINKED_CALL": 27, "MONOMORPHIC_SMIABLE_CALL": 28, "CALL_SITE_DATA": 29, "ICDATA": 30, "MEGAMORPHIC_CACHE": 31, "SUBTYPE_TEST_CACHE": 32, "LOADING_UNIT": 33, "LANGUAGE_ERROR": 36, "UNHANDLED_EXCEPTION": 37, "INSTANCE": 39, "LIBRARY_PREFIX": 40, "TYPE_ARGUMENTS": 41, "TYPE": 43, "FUNCTION_TYPE": 44, "TYPE_REF": 45, "TYPE_PARAMETER": 46, "CLOSURE": 47, "MINT": 51, "DOUBLE": 52, "FLOAT32X4": 55, "INT32X4": 56, "FLOAT64X2": 57, "TYPED_DATA": 59, "EXTERNAL_TYPED_DATA": 60, "TYPED_DATA_VIEW": 61, "CAPABILITY": 64, "RECEIVE_PORT": 65, "SEND_PORT": 66, "STACK_TRACE": 67, "REGEXP": 68, "WEAK_PROPERTY": 69, "FUTURE_OR": 72, "USER_TAG": 73, "TRANSFERABLE_TYPED_DATA": 74, "ARRAY": 75, "IMMUTABLE_ARRAY": 76, "GROWABLE_OBJECT_ARRAY": 54, "STRING": 77, "ONE_BYTE_STRING": 78, "TWO_BYTE_STRING": 79, "NUM_PREDEFINED_CIDS": 148}},
"2.14.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 104, "typed_data_internal_limit": 146, "typed_data_stride": 3, "cids": {"ILLEGAL": 0, "CLASS": 4, "PATCH_CLASS": 5, "FUNCTION": 6, "TYPE_PARAMETERS": 7, "CLOSURE_DATA": 8, "FFI_TRAMPOLINE_DATA": 9, "FIELD": 10, "SCRIPT": 11, "LIBRARY": 12, "NAMESPACE": 13, "KERNEL_PROGRAM_INFO": 14, "WEAK_SERIALIZATION_REFERENCE": 15, "CODE": 16, "OBJECT_POOL": 20, "PC_DESCRIPTORS": 21, "CODE_SOURCE_MAP": 22, "COMPRESSED_STACK_MAPS": 23, "EXCEPTION_HANDLERS": 25, "CONTEXT": 26, "CONTEXT_SCOPE": 27, "SENTINEL": 28, "SINGLE_TARGET_CACHE": 29, "UNLINKED_CALL": 30, "MONOMORPHIC_SMIABLE_CALL": 31, "CALL_SITE_DATA": 32, "ICDATA": 33, "MEGAMORPHIC_CACHE": 34, "SUBTYPE_TEST_CACHE": 35, "LOADING_UNIT": 36, "LANGUAGE_ERROR": 39, "UNHANDLED_EXCEPTION": 40, "INSTANCE": 42, "LIBRARY_PREFIX": 43, "TYPE_ARGUMENTS": 44, "TYPE": 46, "FUNCTION_TYPE": 47, "TYPE_REF": 48, "TYPE_PARAMETER": 49, "CLOSURE": 50, "MINT": 54, "DOUBLE": 55, "FLOAT32X4": 58, "INT32X4": 59, "FLOAT64X2": 60, "TYPED_DATA": 62, "EXTERNAL_TYPED_DATA": 63, "TYPED_DATA_VIEW": 64, "CAPABILITY": 67, "RECEIVE_PORT": 68, "SEND_PORT": 69, "STACK_TRACE": 70, "REGEXP": 71, "WEAK_PROPERTY": 72, "FUTURE_OR": 74, "USER_TAG": 75, "TRANSFERABLE_TYPED_DATA": 76, "ARRAY": 79, "IMMUTABLE_ARRAY": 80, "GROWABLE_OBJECT_ARRAY": 57, "STRING": 81, "ONE_BYTE_STRING": 82, "TWO_BYTE_STRING": 83, "NUM_PREDEFINED_CIDS": 152}},
"2.15.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 106, "typed_data_internal_limit": 148, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 48, "TYPE_REF": 49, "TYPE_PARAMETER": 50, "CLOSURE": 51, "MINT": 55, "DOUBLE": 56, "FLOAT32X4": 58, "INT32X4": 59, "FLOAT64X2": 60, "TYPED_DATA": 62, "EXTERNAL_TYPED_DATA": 63, "TYPED_DATA_VIEW": 64, "CAPABILITY": 67, "RECEIVE_PORT": 68, "SEND_PORT": 69, "STACK_TRACE": 70, "REGEXP": 71, "WEAK_PROPERTY": 72, "FUTURE_OR": 74, "USER_TAG": 75, "TRANSFERABLE_TYPED_DATA": 76, "ARRAY": 81, "IMMUTABLE_ARRAY": 82, "GROWABLE_OBJECT_ARRAY": 83, "STRING": 84, "ONE_BYTE_STRING": 85, "TWO_BYTE_STRING": 86, "NUM_PREDEFINED_CIDS": 154}},
"2.16.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 6, "typed_data_internal_base": 106, "typed_data_internal_limit": 148, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 48, "TYPE_REF": 49, "TYPE_PARAMETER": 50, "CLOSURE": 51, "MINT": 55, "DOUBLE": 56, "FLOAT32X4": 58, "INT32X4": 59, "FLOAT64X2": 60, "TYPED_DATA": 62, "EXTERNAL_TYPED_DATA": 63, "TYPED_DATA_VIEW": 64, "CAPABILITY": 67, "RECEIVE_PORT": 68, "SEND_PORT": 69, "STACK_TRACE": 70, "REGEXP": 71, "WEAK_PROPERTY": 72, "FUTURE_OR": 74, "USER_TAG": 75, "TRANSFERABLE_TYPED_DATA": 76, "ARRAY": 81, "IMMUTABLE_ARRAY": 82, "GROWABLE_OBJECT_ARRAY": 83, "STRING": 84, "ONE_BYTE_STRING": 85, "TWO_BYTE_STRING": 86, "NUM_PREDEFINED_CIDS": 154}},
"2.17.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 6, "typed_data_internal_base": 110, "typed_data_internal_limit": 152, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 52, "TYPE_REF": 53, "TYPE_PARAMETER": 54, "CLOSURE": 55, "MINT": 59, "DOUBLE": 60, "FLOAT32X4": 62, "INT32X4": 63, "FLOAT64X2": 64, "TYPED_DATA": 66, "EXTERNAL_TYPED_DATA": 67, "TYPED_DATA_VIEW": 68, "CAPABILITY": 71, "RECEIVE_PORT": 72, "SEND_PORT": 73, "STACK_TRACE": 74, "REGEXP": 75, "WEAK_PROPERTY": 76, "WEAK_REFERENCE": 77, "FUTURE_OR": 79, "USER_TAG": 80, "TRANSFERABLE_TYPED_DATA": 81, "ARRAY": 86, "IMMUTABLE_ARRAY": 87, "GROWABLE_OBJECT_ARRAY": 88, "STRING": 89, "ONE_BYTE_STRING": 90, "TWO_BYTE_STRING": 91, "NUM_PREDEFINED_CIDS": 158}},
"2.18.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 111, "typed_data_internal_limit": 153, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 52, "TYPE_REF": 53, "TYPE_PARAMETER": 54, "CLOSURE": 55, "MINT": 59, "DOUBLE": 60, "FLOAT32X4": 62, "INT32X4": 63, "FLOAT64X2": 64, "TYPED_DATA": 66, "EXTERNAL_TYPED_DATA": 67, "TYPED_DATA_VIEW": 68, "CAPABILITY": 71, "RECEIVE_PORT": 72, "SEND_PORT": 73, "STACK_TRACE": 74, "SUSPEND_STATE": 75, "REGEXP": 76, "WEAK_PROPERTY": 77, "WEAK_REFERENCE": 78, "FUTURE_OR": 80, "USER_TAG": 81, "TRANSFERABLE_TYPED_DATA": 82, "MAP": 83, "CONST_MAP": 84, "SET": 85, "CONST_SET": 86, "ARRAY": 87, "IMMUTABLE_ARRAY": 88, "GROWABLE_OBJECT_ARRAY": 89, "STRING": 90, "ONE_BYTE_STRING": 91, "TWO_BYTE_STRING": 92, "NUM_PREDEFINED_CIDS": 159}},
"2.18.2": {"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}, "note": "Uses fallback CIDs from 3.9.2 for the in-tree Flutter engine snapshot; not standalone Dart SDK 2.18.2 CIDs."},
"2.18.3": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 111, "typed_data_internal_limit": 153, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 52, "TYPE_REF": 53, "TYPE_PARAMETER": 54, "CLOSURE": 55, "MINT": 59, "DOUBLE": 60, "FLOAT32X4": 62, "INT32X4": 63, "FLOAT64X2": 64, "TYPED_DATA": 66, "EXTERNAL_TYPED_DATA": 67, "TYPED_DATA_VIEW": 68, "CAPABILITY": 71, "RECEIVE_PORT": 72, "SEND_PORT": 73, "STACK_TRACE": 74, "SUSPEND_STATE": 75, "REGEXP": 76, "WEAK_PROPERTY": 77, "WEAK_REFERENCE": 78, "FUTURE_OR": 80, "USER_TAG": 81, "TRANSFERABLE_TYPED_DATA": 82, "MAP": 83, "CONST_MAP": 84, "SET": 85, "CONST_SET": 86, "ARRAY": 87, "IMMUTABLE_ARRAY": 88, "GROWABLE_OBJECT_ARRAY": 89, "STRING": 90, "ONE_BYTE_STRING": 91, "TWO_BYTE_STRING": 92, "NUM_PREDEFINED_CIDS": 159}},
"2.19.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 48, "RECORD_TYPE": 49, "TYPE_REF": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 176}},
"3.0.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 114, "typed_data_internal_limit": 170, "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_REF": 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": 177}},
"3.1.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 176}},
"3.2.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 176}},
"3.3.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 176}},
"3.4.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 111, "typed_data_internal_limit": 167, "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 174}},
"3.5.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 111, "typed_data_internal_limit": 167, "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 174}},
"3.6.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": 33, "MONOMORPHIC_SMIABLE_CALL": 34, "CALL_SITE_DATA": 35, "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.7.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": 33, "MONOMORPHIC_SMIABLE_CALL": 34, "CALL_SITE_DATA": 35, "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.8.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": 33, "MONOMORPHIC_SMIABLE_CALL": 34, "CALL_SITE_DATA": 35, "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.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.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}}
"2.10.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_INT32", "header_fields": 4, "typed_data_internal_base": 108, "typed_data_internal_limit": 150, "typed_data_stride": 3, "cids": {"ILLEGAL": 0, "CLASS": 4, "PATCH_CLASS": 5, "FUNCTION": 6, "CLOSURE_DATA": 7, "FFI_TRAMPOLINE_DATA": 10, "FIELD": 11, "SCRIPT": 12, "LIBRARY": 13, "NAMESPACE": 14, "KERNEL_PROGRAM_INFO": 15, "WEAK_SERIALIZATION_REFERENCE": 77, "CODE": 16, "OBJECT_POOL": 20, "PC_DESCRIPTORS": 21, "CODE_SOURCE_MAP": 22, "COMPRESSED_STACK_MAPS": 23, "LOCAL_VAR_DESCRIPTORS": 24, "EXCEPTION_HANDLERS": 25, "CONTEXT": 26, "CONTEXT_SCOPE": 27, "SINGLE_TARGET_CACHE": 29, "UNLINKED_CALL": 30, "MONOMORPHIC_SMIABLE_CALL": 31, "CALL_SITE_DATA": 32, "ICDATA": 33, "MEGAMORPHIC_CACHE": 34, "SUBTYPE_TEST_CACHE": 35, "LOADING_UNIT": 36, "API_ERROR": 38, "LANGUAGE_ERROR": 39, "UNHANDLED_EXCEPTION": 40, "UNWIND_ERROR": 41, "INSTANCE": 42, "LIBRARY_PREFIX": 43, "TYPE_ARGUMENTS": 44, "TYPE": 46, "TYPE_REF": 47, "TYPE_PARAMETER": 48, "CLOSURE": 49, "MINT": 53, "DOUBLE": 54, "FLOAT32X4": 57, "INT32X4": 58, "FLOAT64X2": 59, "TYPED_DATA": 61, "EXTERNAL_TYPED_DATA": 62, "TYPED_DATA_VIEW": 63, "CAPABILITY": 66, "RECEIVE_PORT": 67, "SEND_PORT": 68, "STACK_TRACE": 69, "REGEXP": 70, "WEAK_PROPERTY": 71, "FUTURE_OR": 74, "USER_TAG": 75, "TRANSFERABLE_TYPED_DATA": 76, "ARRAY": 78, "IMMUTABLE_ARRAY": 79, "GROWABLE_OBJECT_ARRAY": 56, "STRING": 80, "ONE_BYTE_STRING": 81, "TWO_BYTE_STRING": 82, "NUM_PREDEFINED_CIDS": 156}},
"2.12.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_INT32", "header_fields": 5, "typed_data_internal_base": 100, "typed_data_internal_limit": 142, "typed_data_stride": 3, "cids": {"ILLEGAL": 0, "CLASS": 4, "PATCH_CLASS": 5, "FUNCTION": 6, "CLOSURE_DATA": 7, "FFI_TRAMPOLINE_DATA": 8, "FIELD": 9, "SCRIPT": 10, "LIBRARY": 11, "NAMESPACE": 12, "KERNEL_PROGRAM_INFO": 13, "WEAK_SERIALIZATION_REFERENCE": 74, "CODE": 14, "OBJECT_POOL": 17, "PC_DESCRIPTORS": 18, "CODE_SOURCE_MAP": 19, "COMPRESSED_STACK_MAPS": 20, "LOCAL_VAR_DESCRIPTORS": 21, "EXCEPTION_HANDLERS": 22, "CONTEXT": 23, "CONTEXT_SCOPE": 24, "SINGLE_TARGET_CACHE": 25, "UNLINKED_CALL": 26, "MONOMORPHIC_SMIABLE_CALL": 27, "CALL_SITE_DATA": 28, "ICDATA": 29, "MEGAMORPHIC_CACHE": 30, "SUBTYPE_TEST_CACHE": 31, "LOADING_UNIT": 32, "API_ERROR": 34, "LANGUAGE_ERROR": 35, "UNHANDLED_EXCEPTION": 36, "UNWIND_ERROR": 37, "INSTANCE": 38, "LIBRARY_PREFIX": 39, "TYPE_ARGUMENTS": 40, "TYPE": 42, "FUNCTION_TYPE": 43, "TYPE_REF": 44, "TYPE_PARAMETER": 45, "CLOSURE": 46, "MINT": 50, "DOUBLE": 51, "FLOAT32X4": 54, "INT32X4": 55, "FLOAT64X2": 56, "TYPED_DATA": 58, "EXTERNAL_TYPED_DATA": 59, "TYPED_DATA_VIEW": 60, "CAPABILITY": 63, "RECEIVE_PORT": 64, "SEND_PORT": 65, "STACK_TRACE": 66, "REGEXP": 67, "WEAK_PROPERTY": 68, "FUTURE_OR": 71, "USER_TAG": 72, "TRANSFERABLE_TYPED_DATA": 73, "ARRAY": 75, "IMMUTABLE_ARRAY": 76, "GROWABLE_OBJECT_ARRAY": 53, "STRING": 77, "ONE_BYTE_STRING": 78, "TWO_BYTE_STRING": 79, "NUM_PREDEFINED_CIDS": 148}},
"2.13.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_INT32", "header_fields": 5, "typed_data_internal_base": 100, "typed_data_internal_limit": 142, "typed_data_stride": 3, "cids": {"ILLEGAL": 0, "CLASS": 4, "PATCH_CLASS": 5, "FUNCTION": 6, "CLOSURE_DATA": 7, "FFI_TRAMPOLINE_DATA": 8, "FIELD": 9, "SCRIPT": 10, "LIBRARY": 11, "NAMESPACE": 12, "KERNEL_PROGRAM_INFO": 13, "WEAK_SERIALIZATION_REFERENCE": 14, "CODE": 15, "OBJECT_POOL": 18, "PC_DESCRIPTORS": 19, "CODE_SOURCE_MAP": 20, "COMPRESSED_STACK_MAPS": 21, "LOCAL_VAR_DESCRIPTORS": 22, "EXCEPTION_HANDLERS": 23, "CONTEXT": 24, "CONTEXT_SCOPE": 25, "SINGLE_TARGET_CACHE": 26, "UNLINKED_CALL": 27, "MONOMORPHIC_SMIABLE_CALL": 28, "CALL_SITE_DATA": 29, "ICDATA": 30, "MEGAMORPHIC_CACHE": 31, "SUBTYPE_TEST_CACHE": 32, "LOADING_UNIT": 33, "API_ERROR": 35, "LANGUAGE_ERROR": 36, "UNHANDLED_EXCEPTION": 37, "UNWIND_ERROR": 38, "INSTANCE": 39, "LIBRARY_PREFIX": 40, "TYPE_ARGUMENTS": 41, "TYPE": 43, "FUNCTION_TYPE": 44, "TYPE_REF": 45, "TYPE_PARAMETER": 46, "CLOSURE": 47, "MINT": 51, "DOUBLE": 52, "FLOAT32X4": 55, "INT32X4": 56, "FLOAT64X2": 57, "TYPED_DATA": 59, "EXTERNAL_TYPED_DATA": 60, "TYPED_DATA_VIEW": 61, "CAPABILITY": 64, "RECEIVE_PORT": 65, "SEND_PORT": 66, "STACK_TRACE": 67, "REGEXP": 68, "WEAK_PROPERTY": 69, "FUTURE_OR": 72, "USER_TAG": 73, "TRANSFERABLE_TYPED_DATA": 74, "ARRAY": 75, "IMMUTABLE_ARRAY": 76, "GROWABLE_OBJECT_ARRAY": 54, "STRING": 77, "ONE_BYTE_STRING": 78, "TWO_BYTE_STRING": 79, "NUM_PREDEFINED_CIDS": 148}},
"2.14.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 104, "typed_data_internal_limit": 146, "typed_data_stride": 3, "cids": {"ILLEGAL": 0, "CLASS": 4, "PATCH_CLASS": 5, "FUNCTION": 6, "TYPE_PARAMETERS": 7, "CLOSURE_DATA": 8, "FFI_TRAMPOLINE_DATA": 9, "FIELD": 10, "SCRIPT": 11, "LIBRARY": 12, "NAMESPACE": 13, "KERNEL_PROGRAM_INFO": 14, "WEAK_SERIALIZATION_REFERENCE": 15, "CODE": 16, "OBJECT_POOL": 20, "PC_DESCRIPTORS": 21, "CODE_SOURCE_MAP": 22, "COMPRESSED_STACK_MAPS": 23, "LOCAL_VAR_DESCRIPTORS": 24, "EXCEPTION_HANDLERS": 25, "CONTEXT": 26, "CONTEXT_SCOPE": 27, "SENTINEL": 28, "SINGLE_TARGET_CACHE": 29, "UNLINKED_CALL": 30, "MONOMORPHIC_SMIABLE_CALL": 31, "CALL_SITE_DATA": 32, "ICDATA": 33, "MEGAMORPHIC_CACHE": 34, "SUBTYPE_TEST_CACHE": 35, "LOADING_UNIT": 36, "API_ERROR": 38, "LANGUAGE_ERROR": 39, "UNHANDLED_EXCEPTION": 40, "UNWIND_ERROR": 41, "INSTANCE": 42, "LIBRARY_PREFIX": 43, "TYPE_ARGUMENTS": 44, "TYPE": 46, "FUNCTION_TYPE": 47, "TYPE_REF": 48, "TYPE_PARAMETER": 49, "CLOSURE": 50, "MINT": 54, "DOUBLE": 55, "FLOAT32X4": 58, "INT32X4": 59, "FLOAT64X2": 60, "TYPED_DATA": 62, "EXTERNAL_TYPED_DATA": 63, "TYPED_DATA_VIEW": 64, "CAPABILITY": 67, "RECEIVE_PORT": 68, "SEND_PORT": 69, "STACK_TRACE": 70, "REGEXP": 71, "WEAK_PROPERTY": 72, "FUTURE_OR": 74, "USER_TAG": 75, "TRANSFERABLE_TYPED_DATA": 76, "ARRAY": 79, "IMMUTABLE_ARRAY": 80, "GROWABLE_OBJECT_ARRAY": 57, "STRING": 81, "ONE_BYTE_STRING": 82, "TWO_BYTE_STRING": 83, "NUM_PREDEFINED_CIDS": 152}},
"2.15.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 106, "typed_data_internal_limit": 148, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "LOCAL_VAR_DESCRIPTORS": 25, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "API_ERROR": 39, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "UNWIND_ERROR": 42, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 48, "TYPE_REF": 49, "TYPE_PARAMETER": 50, "CLOSURE": 51, "MINT": 55, "DOUBLE": 56, "FLOAT32X4": 58, "INT32X4": 59, "FLOAT64X2": 60, "TYPED_DATA": 62, "EXTERNAL_TYPED_DATA": 63, "TYPED_DATA_VIEW": 64, "CAPABILITY": 67, "RECEIVE_PORT": 68, "SEND_PORT": 69, "STACK_TRACE": 70, "REGEXP": 71, "WEAK_PROPERTY": 72, "FUTURE_OR": 74, "USER_TAG": 75, "TRANSFERABLE_TYPED_DATA": 76, "ARRAY": 81, "IMMUTABLE_ARRAY": 82, "GROWABLE_OBJECT_ARRAY": 83, "STRING": 84, "ONE_BYTE_STRING": 85, "TWO_BYTE_STRING": 86, "NUM_PREDEFINED_CIDS": 154}},
"2.16.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 6, "typed_data_internal_base": 106, "typed_data_internal_limit": 148, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "LOCAL_VAR_DESCRIPTORS": 25, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "API_ERROR": 39, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "UNWIND_ERROR": 42, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 48, "TYPE_REF": 49, "TYPE_PARAMETER": 50, "CLOSURE": 51, "MINT": 55, "DOUBLE": 56, "FLOAT32X4": 58, "INT32X4": 59, "FLOAT64X2": 60, "TYPED_DATA": 62, "EXTERNAL_TYPED_DATA": 63, "TYPED_DATA_VIEW": 64, "CAPABILITY": 67, "RECEIVE_PORT": 68, "SEND_PORT": 69, "STACK_TRACE": 70, "REGEXP": 71, "WEAK_PROPERTY": 72, "FUTURE_OR": 74, "USER_TAG": 75, "TRANSFERABLE_TYPED_DATA": 76, "ARRAY": 81, "IMMUTABLE_ARRAY": 82, "GROWABLE_OBJECT_ARRAY": 83, "STRING": 84, "ONE_BYTE_STRING": 85, "TWO_BYTE_STRING": 86, "NUM_PREDEFINED_CIDS": 154}},
"2.17.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 6, "typed_data_internal_base": 110, "typed_data_internal_limit": 152, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "LOCAL_VAR_DESCRIPTORS": 25, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "API_ERROR": 39, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "UNWIND_ERROR": 42, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 52, "TYPE_REF": 53, "TYPE_PARAMETER": 54, "CLOSURE": 55, "MINT": 59, "DOUBLE": 60, "FLOAT32X4": 62, "INT32X4": 63, "FLOAT64X2": 64, "TYPED_DATA": 66, "EXTERNAL_TYPED_DATA": 67, "TYPED_DATA_VIEW": 68, "CAPABILITY": 71, "RECEIVE_PORT": 72, "SEND_PORT": 73, "STACK_TRACE": 74, "REGEXP": 75, "WEAK_PROPERTY": 76, "WEAK_REFERENCE": 77, "FUTURE_OR": 79, "USER_TAG": 80, "TRANSFERABLE_TYPED_DATA": 81, "ARRAY": 86, "IMMUTABLE_ARRAY": 87, "GROWABLE_OBJECT_ARRAY": 88, "STRING": 89, "ONE_BYTE_STRING": 90, "TWO_BYTE_STRING": 91, "NUM_PREDEFINED_CIDS": 158}},
"2.18.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 111, "typed_data_internal_limit": 153, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "LOCAL_VAR_DESCRIPTORS": 25, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "API_ERROR": 39, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "UNWIND_ERROR": 42, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 52, "TYPE_REF": 53, "TYPE_PARAMETER": 54, "CLOSURE": 55, "MINT": 59, "DOUBLE": 60, "FLOAT32X4": 62, "INT32X4": 63, "FLOAT64X2": 64, "TYPED_DATA": 66, "EXTERNAL_TYPED_DATA": 67, "TYPED_DATA_VIEW": 68, "CAPABILITY": 71, "RECEIVE_PORT": 72, "SEND_PORT": 73, "STACK_TRACE": 74, "SUSPEND_STATE": 75, "REGEXP": 76, "WEAK_PROPERTY": 77, "WEAK_REFERENCE": 78, "FUTURE_OR": 80, "USER_TAG": 81, "TRANSFERABLE_TYPED_DATA": 82, "MAP": 83, "CONST_MAP": 84, "SET": 85, "CONST_SET": 86, "ARRAY": 87, "IMMUTABLE_ARRAY": 88, "GROWABLE_OBJECT_ARRAY": 89, "STRING": 90, "ONE_BYTE_STRING": 91, "TWO_BYTE_STRING": 92, "NUM_PREDEFINED_CIDS": 159}},
"2.18.2": {"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, "LOCAL_VAR_DESCRIPTORS": 27, "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, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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}, "note": "Uses fallback CIDs from 3.9.2 for the in-tree Flutter engine snapshot; not standalone Dart SDK 2.18.2 CIDs."},
"2.18.3": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 111, "typed_data_internal_limit": 153, "typed_data_stride": 3, "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "LOCAL_VAR_DESCRIPTORS": 25, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "API_ERROR": 39, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "UNWIND_ERROR": 42, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 52, "TYPE_REF": 53, "TYPE_PARAMETER": 54, "CLOSURE": 55, "MINT": 59, "DOUBLE": 60, "FLOAT32X4": 62, "INT32X4": 63, "FLOAT64X2": 64, "TYPED_DATA": 66, "EXTERNAL_TYPED_DATA": 67, "TYPED_DATA_VIEW": 68, "CAPABILITY": 71, "RECEIVE_PORT": 72, "SEND_PORT": 73, "STACK_TRACE": 74, "SUSPEND_STATE": 75, "REGEXP": 76, "WEAK_PROPERTY": 77, "WEAK_REFERENCE": 78, "FUTURE_OR": 80, "USER_TAG": 81, "TRANSFERABLE_TYPED_DATA": 82, "MAP": 83, "CONST_MAP": 84, "SET": 85, "CONST_SET": 86, "ARRAY": 87, "IMMUTABLE_ARRAY": 88, "GROWABLE_OBJECT_ARRAY": 89, "STRING": 90, "ONE_BYTE_STRING": 91, "TWO_BYTE_STRING": 92, "NUM_PREDEFINED_CIDS": 159}},
"2.19.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "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, "CODE": 17, "OBJECT_POOL": 21, "PC_DESCRIPTORS": 22, "CODE_SOURCE_MAP": 23, "COMPRESSED_STACK_MAPS": 24, "LOCAL_VAR_DESCRIPTORS": 25, "EXCEPTION_HANDLERS": 26, "CONTEXT": 27, "CONTEXT_SCOPE": 28, "SENTINEL": 29, "SINGLE_TARGET_CACHE": 30, "UNLINKED_CALL": 31, "MONOMORPHIC_SMIABLE_CALL": 32, "CALL_SITE_DATA": 33, "ICDATA": 34, "MEGAMORPHIC_CACHE": 35, "SUBTYPE_TEST_CACHE": 36, "LOADING_UNIT": 37, "API_ERROR": 39, "LANGUAGE_ERROR": 40, "UNHANDLED_EXCEPTION": 41, "UNWIND_ERROR": 42, "INSTANCE": 43, "LIBRARY_PREFIX": 44, "TYPE_ARGUMENTS": 45, "TYPE": 47, "FUNCTION_TYPE": 48, "RECORD_TYPE": 49, "TYPE_REF": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 176}},
"3.0.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "header_fields": 5, "typed_data_internal_base": 114, "typed_data_internal_limit": 170, "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "LOCAL_VAR_DESCRIPTORS": 26, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "API_ERROR": 40, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "UNWIND_ERROR": 43, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_REF": 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": 177}},
"3.1.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "LOCAL_VAR_DESCRIPTORS": 26, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "API_ERROR": 40, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "UNWIND_ERROR": 43, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 176}},
"3.2.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "LOCAL_VAR_DESCRIPTORS": 26, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "API_ERROR": 40, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "UNWIND_ERROR": 43, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 176}},
"3.3.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "CID_SHIFT1", "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "LOCAL_VAR_DESCRIPTORS": 26, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "API_ERROR": 40, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "UNWIND_ERROR": 43, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 176}},
"3.4.0": {"cws": 8, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 111, "typed_data_internal_limit": 167, "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "LOCAL_VAR_DESCRIPTORS": 26, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "API_ERROR": 40, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "UNWIND_ERROR": 43, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 174}},
"3.5.0": {"cws": 4, "heap_object_tag": 1, "max_alignment": 16, "it_cap": 20000, "tag_style": "OBJECT_HEADER", "header_fields": 5, "typed_data_internal_base": 111, "typed_data_internal_limit": 167, "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": 22, "PC_DESCRIPTORS": 23, "CODE_SOURCE_MAP": 24, "COMPRESSED_STACK_MAPS": 25, "LOCAL_VAR_DESCRIPTORS": 26, "EXCEPTION_HANDLERS": 27, "CONTEXT": 28, "CONTEXT_SCOPE": 29, "SENTINEL": 30, "SINGLE_TARGET_CACHE": 31, "UNLINKED_CALL": 32, "MONOMORPHIC_SMIABLE_CALL": 33, "CALL_SITE_DATA": 34, "ICDATA": 35, "MEGAMORPHIC_CACHE": 36, "SUBTYPE_TEST_CACHE": 37, "LOADING_UNIT": 38, "API_ERROR": 40, "LANGUAGE_ERROR": 41, "UNHANDLED_EXCEPTION": 42, "UNWIND_ERROR": 43, "INSTANCE": 44, "LIBRARY_PREFIX": 45, "TYPE_ARGUMENTS": 46, "TYPE": 48, "FUNCTION_TYPE": 49, "RECORD_TYPE": 50, "TYPE_PARAMETER": 51, "CLOSURE": 56, "MINT": 60, "DOUBLE": 61, "FLOAT32X4": 63, "INT32X4": 64, "FLOAT64X2": 65, "RECORD": 66, "TYPED_DATA": 68, "EXTERNAL_TYPED_DATA": 69, "TYPED_DATA_VIEW": 70, "CAPABILITY": 73, "RECEIVE_PORT": 74, "SEND_PORT": 75, "STACK_TRACE": 76, "SUSPEND_STATE": 77, "REGEXP": 78, "WEAK_PROPERTY": 79, "WEAK_REFERENCE": 80, "FUTURE_OR": 82, "USER_TAG": 83, "TRANSFERABLE_TYPED_DATA": 84, "MAP": 85, "CONST_MAP": 86, "SET": 87, "CONST_SET": 88, "ARRAY": 89, "IMMUTABLE_ARRAY": 90, "GROWABLE_OBJECT_ARRAY": 91, "STRING": 92, "ONE_BYTE_STRING": 93, "TWO_BYTE_STRING": 94, "NUM_PREDEFINED_CIDS": 174}},
"3.6.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, "LOCAL_VAR_DESCRIPTORS": 27, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 33, "MONOMORPHIC_SMIABLE_CALL": 34, "CALL_SITE_DATA": 35, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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.7.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, "LOCAL_VAR_DESCRIPTORS": 27, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 33, "MONOMORPHIC_SMIABLE_CALL": 34, "CALL_SITE_DATA": 35, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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.8.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, "LOCAL_VAR_DESCRIPTORS": 27, "EXCEPTION_HANDLERS": 28, "CONTEXT": 29, "CONTEXT_SCOPE": 30, "SENTINEL": 31, "SINGLE_TARGET_CACHE": 32, "UNLINKED_CALL": 33, "MONOMORPHIC_SMIABLE_CALL": 34, "CALL_SITE_DATA": 35, "ICDATA": 36, "MEGAMORPHIC_CACHE": 37, "SUBTYPE_TEST_CACHE": 38, "LOADING_UNIT": 39, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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.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, "LOCAL_VAR_DESCRIPTORS": 27, "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, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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, "LOCAL_VAR_DESCRIPTORS": 27, "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, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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, "LOCAL_VAR_DESCRIPTORS": 27, "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, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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, "LOCAL_VAR_DESCRIPTORS": 27, "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, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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, "LOCAL_VAR_DESCRIPTORS": 27, "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, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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, "LOCAL_VAR_DESCRIPTORS": 27, "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, "API_ERROR": 41, "LANGUAGE_ERROR": 42, "UNHANDLED_EXCEPTION": 43, "UNWIND_ERROR": 44, "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",
+3
View File
@@ -99,6 +99,7 @@ CID_KIND_TO_CLASS_NAME = [
("PC_DESCRIPTORS", "PcDescriptors"),
("CODE_SOURCE_MAP", "CodeSourceMap"),
("COMPRESSED_STACK_MAPS", "CompressedStackMaps"),
("LOCAL_VAR_DESCRIPTORS", "LocalVarDescriptors"),
("EXCEPTION_HANDLERS", "ExceptionHandlers"),
("CONTEXT", "Context"),
("CONTEXT_SCOPE", "ContextScope"),
@@ -111,8 +112,10 @@ CID_KIND_TO_CLASS_NAME = [
("MEGAMORPHIC_CACHE", "MegamorphicCache"),
("SUBTYPE_TEST_CACHE", "SubtypeTestCache"),
("LOADING_UNIT", "LoadingUnit"),
("API_ERROR", "ApiError"),
("LANGUAGE_ERROR", "LanguageError"),
("UNHANDLED_EXCEPTION", "UnhandledException"),
("UNWIND_ERROR", "UnwindError"),
("INSTANCE", "Instance"),
("LIBRARY_PREFIX", "LibraryPrefix"),
("TYPE_ARGUMENTS", "TypeArguments"),
+26 -6
View File
@@ -179,13 +179,24 @@ static FILE *open_payload_temp(char **out_path) {
FILE *out = try_open_temp_path (r_file_temp ("r2flutter-dart-app-snap"), out_path);
if (!out) {
char *name = r_str_newf ("r2flutter-dart-app-snap.%" PFMT64x, (ut64)r_time_now ());
char *path = name? r_file_new (P_tmpdir, name, NULL): NULL;
char *tmpdir = r_file_tmpdir ();
char *path = (name && tmpdir)? r_file_new (tmpdir, name, NULL): NULL;
free (tmpdir);
free (name);
out = try_open_temp_path (path, out_path);
}
return out;
}
// msvc has no fseeko, but it ships an equivalent 64bit seek
static bool payload_seek(FILE *f, ut64 off) {
#if defined(_MSC_VER)
return _fseeki64 (f, (__int64)off, SEEK_SET) == 0;
#else
return fseeko (f, (off_t)off, SEEK_SET) == 0;
#endif
}
char *dart_app_extract_payload(const char *path, const DartAppEmbeddedPayload *payload) {
if (R_STR_ISEMPTY (path) || !payload || !payload->payload_size) {
return NULL;
@@ -202,7 +213,7 @@ char *dart_app_extract_payload(const char *path, const DartAppEmbeddedPayload *p
fclose (in);
return NULL;
}
bool ok = fseeko (in, (off_t)payload->payload_offset, SEEK_SET) == 0;
bool ok = payload_seek (in, payload->payload_offset);
ut64 remaining = payload->payload_size;
ut8 buf[65536];
while (ok && remaining > 0) {
@@ -254,6 +265,9 @@ static int dart_function_cmp(const DartFunction *fa, const DartFunction *fb) {
return 0;
}
// Above placeholder names (func.*, method.fn_*) but below any resolved name.
#define DART_CLASS_METHOD_NAME_QUALITY 20
static int dart_function_name_quality(const char *name) {
if (R_STR_ISEMPTY (name)) {
return 0;
@@ -465,14 +479,17 @@ static char *dart_format_method_full_name(const DartClassInfo *ci, const DartMet
if (!mi || R_STR_ISEMPTY (mi->name)) {
return NULL;
}
char *lib = dart_sanitize_component (ci && ci->library_name? ci->library_name: "app", true);
// Without a library name use the InstructionTable form (method.Owner.leaf)
// so both sources agree on the name of the same entry.
char *lib = ci && ci->library_name? dart_sanitize_component (ci->library_name, true): NULL;
char *owner = dart_sanitize_component (ci && ci->name? ci->name: mi->owner_name, false);
char *leaf = dart_format_method_leaf_name (ci? ci->name: mi->owner_name, mi);
const char *name = leaf? leaf: mi->name;
char *out = NULL;
if (R_STR_ISNOTEMPTY (owner)) {
out = r_str_newf ("method.%s.%s.%s", lib, owner, leaf? leaf: mi->name);
out = lib? r_str_newf ("method.%s.%s.%s", lib, owner, name): r_str_newf ("method.%s.%s", owner, name);
} else {
out = r_str_newf ("method.%s..%s", lib, leaf? leaf: mi->name);
out = lib? r_str_newf ("method.%s..%s", lib, name): r_str_newf ("method.%s", name);
}
r_name_filter (out, 0);
free (lib);
@@ -522,11 +539,14 @@ static void dart_app_merge_class_methods(DartApp *app) {
continue;
}
char *fullname = dart_format_method_full_name (ci, mi);
// InstructionTable names stay authoritative: deduplicated code is
// shared by several methods, so class metadata only fills the
// placeholder names the table could not resolve.
dart_app_add_or_update_fn (app,
fullname? fullname: mi->name,
dart_normalize_code_addr (mi->entry_point),
0,
dart_function_name_quality (fullname? fullname: mi->name),
R_MIN (dart_function_name_quality (fullname? fullname: mi->name), DART_CLASS_METHOD_NAME_QUALITY),
mi->signature);
free (fullname);
}
+29 -26
View File
@@ -17,32 +17,32 @@ typedef struct {
static const DartCidTable cid_tables[] = {
// clang-format off
{ "2.10.0", { CID (ILLEGAL, 0), CID (CLASS, 4), CID (PATCH_CLASS, 5), CID (FUNCTION, 6), CID (CLOSURE_DATA, 7), 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, 77), CID (CODE, 16), CID (OBJECT_POOL, 20), CID (PC_DESCRIPTORS, 21), CID (CODE_SOURCE_MAP, 22), CID (COMPRESSED_STACK_MAPS, 23), CID (EXCEPTION_HANDLERS, 25), CID (CONTEXT, 26), CID (CONTEXT_SCOPE, 27), CID (SINGLE_TARGET_CACHE, 29), CID (UNLINKED_CALL, 30), CID (MONOMORPHIC_SMIABLE_CALL, 31), CID (CALL_SITE_DATA, 32), CID (ICDATA, 33), CID (MEGAMORPHIC_CACHE, 34), CID (SUBTYPE_TEST_CACHE, 35), CID (LOADING_UNIT, 36), CID (LANGUAGE_ERROR, 39), CID (UNHANDLED_EXCEPTION, 40), CID (INSTANCE, 42), CID (LIBRARY_PREFIX, 43), CID (TYPE_ARGUMENTS, 44), CID (TYPE, 46), CID (TYPE_REF, 47), CID (TYPE_PARAMETER, 48), CID (CLOSURE, 49), CID (MINT, 53), CID (DOUBLE, 54), CID (FLOAT32X4, 57), CID (INT32X4, 58), CID (FLOAT64X2, 59), CID (TYPED_DATA, 61), CID (EXTERNAL_TYPED_DATA, 62), CID (TYPED_DATA_VIEW, 63), CID (CAPABILITY, 66), CID (RECEIVE_PORT, 67), CID (SEND_PORT, 68), CID (STACK_TRACE, 69), CID (REGEXP, 70), CID (WEAK_PROPERTY, 71), CID (FUTURE_OR, 74), CID (USER_TAG, 75), CID (TRANSFERABLE_TYPED_DATA, 76), CID (ARRAY, 78), CID (IMMUTABLE_ARRAY, 79), CID (GROWABLE_OBJECT_ARRAY, 56), CID (STRING, 80), CID (ONE_BYTE_STRING, 81), CID (TWO_BYTE_STRING, 82), CID (NUM_PREDEFINED_CIDS, 156) }, 108, 150, 3 },
{ "2.12.0", { CID (ILLEGAL, 0), CID (CLASS, 4), CID (PATCH_CLASS, 5), CID (FUNCTION, 6), CID (CLOSURE_DATA, 7), CID (FFI_TRAMPOLINE_DATA, 8), CID (FIELD, 9), CID (SCRIPT, 10), CID (LIBRARY, 11), CID (NAMESPACE, 12), CID (KERNEL_PROGRAM_INFO, 13), CID (WEAK_SERIALIZATION_REFERENCE, 74), CID (CODE, 14), CID (OBJECT_POOL, 17), CID (PC_DESCRIPTORS, 18), CID (CODE_SOURCE_MAP, 19), CID (COMPRESSED_STACK_MAPS, 20), CID (EXCEPTION_HANDLERS, 22), CID (CONTEXT, 23), CID (CONTEXT_SCOPE, 24), CID (SINGLE_TARGET_CACHE, 25), CID (UNLINKED_CALL, 26), CID (MONOMORPHIC_SMIABLE_CALL, 27), CID (CALL_SITE_DATA, 28), CID (ICDATA, 29), CID (MEGAMORPHIC_CACHE, 30), CID (SUBTYPE_TEST_CACHE, 31), CID (LOADING_UNIT, 32), CID (LANGUAGE_ERROR, 35), CID (UNHANDLED_EXCEPTION, 36), CID (INSTANCE, 38), CID (LIBRARY_PREFIX, 39), CID (TYPE_ARGUMENTS, 40), CID (TYPE, 42), CID (FUNCTION_TYPE, 43), CID (TYPE_REF, 44), CID (TYPE_PARAMETER, 45), CID (CLOSURE, 46), CID (MINT, 50), CID (DOUBLE, 51), CID (FLOAT32X4, 54), CID (INT32X4, 55), CID (FLOAT64X2, 56), CID (TYPED_DATA, 58), CID (EXTERNAL_TYPED_DATA, 59), CID (TYPED_DATA_VIEW, 60), CID (CAPABILITY, 63), CID (RECEIVE_PORT, 64), CID (SEND_PORT, 65), CID (STACK_TRACE, 66), CID (REGEXP, 67), CID (WEAK_PROPERTY, 68), CID (FUTURE_OR, 71), CID (USER_TAG, 72), CID (TRANSFERABLE_TYPED_DATA, 73), CID (ARRAY, 75), CID (IMMUTABLE_ARRAY, 76), CID (GROWABLE_OBJECT_ARRAY, 53), CID (STRING, 77), CID (ONE_BYTE_STRING, 78), CID (TWO_BYTE_STRING, 79), CID (NUM_PREDEFINED_CIDS, 148) }, 100, 142, 3 },
{ "2.13.0", { CID (ILLEGAL, 0), CID (CLASS, 4), CID (PATCH_CLASS, 5), CID (FUNCTION, 6), CID (CLOSURE_DATA, 7), CID (FFI_TRAMPOLINE_DATA, 8), CID (FIELD, 9), CID (SCRIPT, 10), CID (LIBRARY, 11), CID (NAMESPACE, 12), CID (KERNEL_PROGRAM_INFO, 13), CID (WEAK_SERIALIZATION_REFERENCE, 14), CID (CODE, 15), CID (OBJECT_POOL, 18), CID (PC_DESCRIPTORS, 19), CID (CODE_SOURCE_MAP, 20), CID (COMPRESSED_STACK_MAPS, 21), CID (EXCEPTION_HANDLERS, 23), CID (CONTEXT, 24), CID (CONTEXT_SCOPE, 25), CID (SINGLE_TARGET_CACHE, 26), CID (UNLINKED_CALL, 27), CID (MONOMORPHIC_SMIABLE_CALL, 28), CID (CALL_SITE_DATA, 29), CID (ICDATA, 30), CID (MEGAMORPHIC_CACHE, 31), CID (SUBTYPE_TEST_CACHE, 32), CID (LOADING_UNIT, 33), CID (LANGUAGE_ERROR, 36), CID (UNHANDLED_EXCEPTION, 37), CID (INSTANCE, 39), CID (LIBRARY_PREFIX, 40), CID (TYPE_ARGUMENTS, 41), CID (TYPE, 43), CID (FUNCTION_TYPE, 44), CID (TYPE_REF, 45), CID (TYPE_PARAMETER, 46), CID (CLOSURE, 47), CID (MINT, 51), CID (DOUBLE, 52), CID (FLOAT32X4, 55), CID (INT32X4, 56), CID (FLOAT64X2, 57), CID (TYPED_DATA, 59), CID (EXTERNAL_TYPED_DATA, 60), CID (TYPED_DATA_VIEW, 61), CID (CAPABILITY, 64), CID (RECEIVE_PORT, 65), CID (SEND_PORT, 66), CID (STACK_TRACE, 67), CID (REGEXP, 68), CID (WEAK_PROPERTY, 69), CID (FUTURE_OR, 72), CID (USER_TAG, 73), CID (TRANSFERABLE_TYPED_DATA, 74), CID (ARRAY, 75), CID (IMMUTABLE_ARRAY, 76), CID (GROWABLE_OBJECT_ARRAY, 54), CID (STRING, 77), CID (ONE_BYTE_STRING, 78), CID (TWO_BYTE_STRING, 79), CID (NUM_PREDEFINED_CIDS, 148) }, 100, 142, 3 },
{ "2.14.0", { CID (ILLEGAL, 0), CID (CLASS, 4), CID (PATCH_CLASS, 5), CID (FUNCTION, 6), CID (TYPE_PARAMETERS, 7), CID (CLOSURE_DATA, 8), CID (FFI_TRAMPOLINE_DATA, 9), CID (FIELD, 10), CID (SCRIPT, 11), CID (LIBRARY, 12), CID (NAMESPACE, 13), CID (KERNEL_PROGRAM_INFO, 14), CID (WEAK_SERIALIZATION_REFERENCE, 15), CID (CODE, 16), CID (OBJECT_POOL, 20), CID (PC_DESCRIPTORS, 21), CID (CODE_SOURCE_MAP, 22), CID (COMPRESSED_STACK_MAPS, 23), CID (EXCEPTION_HANDLERS, 25), CID (CONTEXT, 26), CID (CONTEXT_SCOPE, 27), CID (SENTINEL, 28), CID (SINGLE_TARGET_CACHE, 29), CID (UNLINKED_CALL, 30), CID (MONOMORPHIC_SMIABLE_CALL, 31), CID (CALL_SITE_DATA, 32), CID (ICDATA, 33), CID (MEGAMORPHIC_CACHE, 34), CID (SUBTYPE_TEST_CACHE, 35), CID (LOADING_UNIT, 36), CID (LANGUAGE_ERROR, 39), CID (UNHANDLED_EXCEPTION, 40), CID (INSTANCE, 42), CID (LIBRARY_PREFIX, 43), CID (TYPE_ARGUMENTS, 44), CID (TYPE, 46), CID (FUNCTION_TYPE, 47), CID (TYPE_REF, 48), CID (TYPE_PARAMETER, 49), CID (CLOSURE, 50), CID (MINT, 54), CID (DOUBLE, 55), CID (FLOAT32X4, 58), CID (INT32X4, 59), CID (FLOAT64X2, 60), CID (TYPED_DATA, 62), CID (EXTERNAL_TYPED_DATA, 63), CID (TYPED_DATA_VIEW, 64), CID (CAPABILITY, 67), CID (RECEIVE_PORT, 68), CID (SEND_PORT, 69), CID (STACK_TRACE, 70), CID (REGEXP, 71), CID (WEAK_PROPERTY, 72), CID (FUTURE_OR, 74), CID (USER_TAG, 75), CID (TRANSFERABLE_TYPED_DATA, 76), CID (ARRAY, 79), CID (IMMUTABLE_ARRAY, 80), CID (GROWABLE_OBJECT_ARRAY, 57), CID (STRING, 81), CID (ONE_BYTE_STRING, 82), CID (TWO_BYTE_STRING, 83), CID (NUM_PREDEFINED_CIDS, 152) }, 104, 146, 3 },
{ "2.15.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 48), CID (TYPE_REF, 49), CID (TYPE_PARAMETER, 50), CID (CLOSURE, 51), CID (MINT, 55), CID (DOUBLE, 56), CID (FLOAT32X4, 58), CID (INT32X4, 59), CID (FLOAT64X2, 60), CID (TYPED_DATA, 62), CID (EXTERNAL_TYPED_DATA, 63), CID (TYPED_DATA_VIEW, 64), CID (CAPABILITY, 67), CID (RECEIVE_PORT, 68), CID (SEND_PORT, 69), CID (STACK_TRACE, 70), CID (REGEXP, 71), CID (WEAK_PROPERTY, 72), CID (FUTURE_OR, 74), CID (USER_TAG, 75), CID (TRANSFERABLE_TYPED_DATA, 76), CID (ARRAY, 81), CID (IMMUTABLE_ARRAY, 82), CID (GROWABLE_OBJECT_ARRAY, 83), CID (STRING, 84), CID (ONE_BYTE_STRING, 85), CID (TWO_BYTE_STRING, 86), CID (NUM_PREDEFINED_CIDS, 154) }, 106, 148, 3 },
{ "2.16.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 48), CID (TYPE_REF, 49), CID (TYPE_PARAMETER, 50), CID (CLOSURE, 51), CID (MINT, 55), CID (DOUBLE, 56), CID (FLOAT32X4, 58), CID (INT32X4, 59), CID (FLOAT64X2, 60), CID (TYPED_DATA, 62), CID (EXTERNAL_TYPED_DATA, 63), CID (TYPED_DATA_VIEW, 64), CID (CAPABILITY, 67), CID (RECEIVE_PORT, 68), CID (SEND_PORT, 69), CID (STACK_TRACE, 70), CID (REGEXP, 71), CID (WEAK_PROPERTY, 72), CID (FUTURE_OR, 74), CID (USER_TAG, 75), CID (TRANSFERABLE_TYPED_DATA, 76), CID (ARRAY, 81), CID (IMMUTABLE_ARRAY, 82), CID (GROWABLE_OBJECT_ARRAY, 83), CID (STRING, 84), CID (ONE_BYTE_STRING, 85), CID (TWO_BYTE_STRING, 86), CID (NUM_PREDEFINED_CIDS, 154) }, 106, 148, 3 },
{ "2.17.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 52), CID (TYPE_REF, 53), CID (TYPE_PARAMETER, 54), CID (CLOSURE, 55), CID (MINT, 59), CID (DOUBLE, 60), CID (FLOAT32X4, 62), CID (INT32X4, 63), CID (FLOAT64X2, 64), CID (TYPED_DATA, 66), CID (EXTERNAL_TYPED_DATA, 67), CID (TYPED_DATA_VIEW, 68), CID (CAPABILITY, 71), CID (RECEIVE_PORT, 72), CID (SEND_PORT, 73), CID (STACK_TRACE, 74), CID (REGEXP, 75), CID (WEAK_PROPERTY, 76), CID (WEAK_REFERENCE, 77), CID (FUTURE_OR, 79), CID (USER_TAG, 80), CID (TRANSFERABLE_TYPED_DATA, 81), CID (ARRAY, 86), CID (IMMUTABLE_ARRAY, 87), CID (GROWABLE_OBJECT_ARRAY, 88), CID (STRING, 89), CID (ONE_BYTE_STRING, 90), CID (TWO_BYTE_STRING, 91), CID (NUM_PREDEFINED_CIDS, 158) }, 110, 152, 3 },
{ "2.18.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 52), CID (TYPE_REF, 53), CID (TYPE_PARAMETER, 54), CID (CLOSURE, 55), CID (MINT, 59), CID (DOUBLE, 60), CID (FLOAT32X4, 62), CID (INT32X4, 63), CID (FLOAT64X2, 64), CID (TYPED_DATA, 66), CID (EXTERNAL_TYPED_DATA, 67), CID (TYPED_DATA_VIEW, 68), CID (CAPABILITY, 71), CID (RECEIVE_PORT, 72), CID (SEND_PORT, 73), CID (STACK_TRACE, 74), CID (SUSPEND_STATE, 75), CID (REGEXP, 76), CID (WEAK_PROPERTY, 77), CID (WEAK_REFERENCE, 78), CID (FUTURE_OR, 80), CID (USER_TAG, 81), CID (TRANSFERABLE_TYPED_DATA, 82), CID (MAP, 83), CID (CONST_MAP, 84), CID (SET, 85), CID (CONST_SET, 86), CID (ARRAY, 87), CID (IMMUTABLE_ARRAY, 88), CID (GROWABLE_OBJECT_ARRAY, 89), CID (STRING, 90), CID (ONE_BYTE_STRING, 91), CID (TWO_BYTE_STRING, 92), CID (NUM_PREDEFINED_CIDS, 159) }, 111, 153, 3 },
{ "2.18.2", { 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 },
{ "2.18.3", { 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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 52), CID (TYPE_REF, 53), CID (TYPE_PARAMETER, 54), CID (CLOSURE, 55), CID (MINT, 59), CID (DOUBLE, 60), CID (FLOAT32X4, 62), CID (INT32X4, 63), CID (FLOAT64X2, 64), CID (TYPED_DATA, 66), CID (EXTERNAL_TYPED_DATA, 67), CID (TYPED_DATA_VIEW, 68), CID (CAPABILITY, 71), CID (RECEIVE_PORT, 72), CID (SEND_PORT, 73), CID (STACK_TRACE, 74), CID (SUSPEND_STATE, 75), CID (REGEXP, 76), CID (WEAK_PROPERTY, 77), CID (WEAK_REFERENCE, 78), CID (FUTURE_OR, 80), CID (USER_TAG, 81), CID (TRANSFERABLE_TYPED_DATA, 82), CID (MAP, 83), CID (CONST_MAP, 84), CID (SET, 85), CID (CONST_SET, 86), CID (ARRAY, 87), CID (IMMUTABLE_ARRAY, 88), CID (GROWABLE_OBJECT_ARRAY, 89), CID (STRING, 90), CID (ONE_BYTE_STRING, 91), CID (TWO_BYTE_STRING, 92), CID (NUM_PREDEFINED_CIDS, 159) }, 111, 153, 3 },
{ "2.19.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 48), CID (RECORD_TYPE, 49), CID (TYPE_REF, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
{ "3.0.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_REF, 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, 177) }, 114, 170, 4 },
{ "3.1.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
{ "3.2.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
{ "3.3.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
{ "3.4.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 174) }, 111, 167, 4 },
{ "3.5.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 174) }, 111, 167, 4 },
{ "3.6.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, 33), CID (MONOMORPHIC_SMIABLE_CALL, 34), CID (CALL_SITE_DATA, 35), 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.7.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, 33), CID (MONOMORPHIC_SMIABLE_CALL, 34), CID (CALL_SITE_DATA, 35), 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.8.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, 33), CID (MONOMORPHIC_SMIABLE_CALL, 34), CID (CALL_SITE_DATA, 35), 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.9.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.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 },
{ "2.10.0", { CID (ILLEGAL, 0), CID (CLASS, 4), CID (PATCH_CLASS, 5), CID (FUNCTION, 6), CID (CLOSURE_DATA, 7), 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, 77), CID (CODE, 16), CID (OBJECT_POOL, 20), CID (PC_DESCRIPTORS, 21), CID (CODE_SOURCE_MAP, 22), CID (COMPRESSED_STACK_MAPS, 23), CID (LOCAL_VAR_DESCRIPTORS, 24), CID (EXCEPTION_HANDLERS, 25), CID (CONTEXT, 26), CID (CONTEXT_SCOPE, 27), CID (SINGLE_TARGET_CACHE, 29), CID (UNLINKED_CALL, 30), CID (MONOMORPHIC_SMIABLE_CALL, 31), CID (CALL_SITE_DATA, 32), CID (ICDATA, 33), CID (MEGAMORPHIC_CACHE, 34), CID (SUBTYPE_TEST_CACHE, 35), CID (LOADING_UNIT, 36), CID (API_ERROR, 38), CID (LANGUAGE_ERROR, 39), CID (UNHANDLED_EXCEPTION, 40), CID (UNWIND_ERROR, 41), CID (INSTANCE, 42), CID (LIBRARY_PREFIX, 43), CID (TYPE_ARGUMENTS, 44), CID (TYPE, 46), CID (TYPE_REF, 47), CID (TYPE_PARAMETER, 48), CID (CLOSURE, 49), CID (MINT, 53), CID (DOUBLE, 54), CID (FLOAT32X4, 57), CID (INT32X4, 58), CID (FLOAT64X2, 59), CID (TYPED_DATA, 61), CID (EXTERNAL_TYPED_DATA, 62), CID (TYPED_DATA_VIEW, 63), CID (CAPABILITY, 66), CID (RECEIVE_PORT, 67), CID (SEND_PORT, 68), CID (STACK_TRACE, 69), CID (REGEXP, 70), CID (WEAK_PROPERTY, 71), CID (FUTURE_OR, 74), CID (USER_TAG, 75), CID (TRANSFERABLE_TYPED_DATA, 76), CID (ARRAY, 78), CID (IMMUTABLE_ARRAY, 79), CID (GROWABLE_OBJECT_ARRAY, 56), CID (STRING, 80), CID (ONE_BYTE_STRING, 81), CID (TWO_BYTE_STRING, 82), CID (NUM_PREDEFINED_CIDS, 156) }, 108, 150, 3 },
{ "2.12.0", { CID (ILLEGAL, 0), CID (CLASS, 4), CID (PATCH_CLASS, 5), CID (FUNCTION, 6), CID (CLOSURE_DATA, 7), CID (FFI_TRAMPOLINE_DATA, 8), CID (FIELD, 9), CID (SCRIPT, 10), CID (LIBRARY, 11), CID (NAMESPACE, 12), CID (KERNEL_PROGRAM_INFO, 13), CID (WEAK_SERIALIZATION_REFERENCE, 74), CID (CODE, 14), CID (OBJECT_POOL, 17), CID (PC_DESCRIPTORS, 18), CID (CODE_SOURCE_MAP, 19), CID (COMPRESSED_STACK_MAPS, 20), CID (LOCAL_VAR_DESCRIPTORS, 21), CID (EXCEPTION_HANDLERS, 22), CID (CONTEXT, 23), CID (CONTEXT_SCOPE, 24), CID (SINGLE_TARGET_CACHE, 25), CID (UNLINKED_CALL, 26), CID (MONOMORPHIC_SMIABLE_CALL, 27), CID (CALL_SITE_DATA, 28), CID (ICDATA, 29), CID (MEGAMORPHIC_CACHE, 30), CID (SUBTYPE_TEST_CACHE, 31), CID (LOADING_UNIT, 32), CID (API_ERROR, 34), CID (LANGUAGE_ERROR, 35), CID (UNHANDLED_EXCEPTION, 36), CID (UNWIND_ERROR, 37), CID (INSTANCE, 38), CID (LIBRARY_PREFIX, 39), CID (TYPE_ARGUMENTS, 40), CID (TYPE, 42), CID (FUNCTION_TYPE, 43), CID (TYPE_REF, 44), CID (TYPE_PARAMETER, 45), CID (CLOSURE, 46), CID (MINT, 50), CID (DOUBLE, 51), CID (FLOAT32X4, 54), CID (INT32X4, 55), CID (FLOAT64X2, 56), CID (TYPED_DATA, 58), CID (EXTERNAL_TYPED_DATA, 59), CID (TYPED_DATA_VIEW, 60), CID (CAPABILITY, 63), CID (RECEIVE_PORT, 64), CID (SEND_PORT, 65), CID (STACK_TRACE, 66), CID (REGEXP, 67), CID (WEAK_PROPERTY, 68), CID (FUTURE_OR, 71), CID (USER_TAG, 72), CID (TRANSFERABLE_TYPED_DATA, 73), CID (ARRAY, 75), CID (IMMUTABLE_ARRAY, 76), CID (GROWABLE_OBJECT_ARRAY, 53), CID (STRING, 77), CID (ONE_BYTE_STRING, 78), CID (TWO_BYTE_STRING, 79), CID (NUM_PREDEFINED_CIDS, 148) }, 100, 142, 3 },
{ "2.13.0", { CID (ILLEGAL, 0), CID (CLASS, 4), CID (PATCH_CLASS, 5), CID (FUNCTION, 6), CID (CLOSURE_DATA, 7), CID (FFI_TRAMPOLINE_DATA, 8), CID (FIELD, 9), CID (SCRIPT, 10), CID (LIBRARY, 11), CID (NAMESPACE, 12), CID (KERNEL_PROGRAM_INFO, 13), CID (WEAK_SERIALIZATION_REFERENCE, 14), CID (CODE, 15), CID (OBJECT_POOL, 18), CID (PC_DESCRIPTORS, 19), CID (CODE_SOURCE_MAP, 20), CID (COMPRESSED_STACK_MAPS, 21), CID (LOCAL_VAR_DESCRIPTORS, 22), CID (EXCEPTION_HANDLERS, 23), CID (CONTEXT, 24), CID (CONTEXT_SCOPE, 25), CID (SINGLE_TARGET_CACHE, 26), CID (UNLINKED_CALL, 27), CID (MONOMORPHIC_SMIABLE_CALL, 28), CID (CALL_SITE_DATA, 29), CID (ICDATA, 30), CID (MEGAMORPHIC_CACHE, 31), CID (SUBTYPE_TEST_CACHE, 32), CID (LOADING_UNIT, 33), CID (API_ERROR, 35), CID (LANGUAGE_ERROR, 36), CID (UNHANDLED_EXCEPTION, 37), CID (UNWIND_ERROR, 38), CID (INSTANCE, 39), CID (LIBRARY_PREFIX, 40), CID (TYPE_ARGUMENTS, 41), CID (TYPE, 43), CID (FUNCTION_TYPE, 44), CID (TYPE_REF, 45), CID (TYPE_PARAMETER, 46), CID (CLOSURE, 47), CID (MINT, 51), CID (DOUBLE, 52), CID (FLOAT32X4, 55), CID (INT32X4, 56), CID (FLOAT64X2, 57), CID (TYPED_DATA, 59), CID (EXTERNAL_TYPED_DATA, 60), CID (TYPED_DATA_VIEW, 61), CID (CAPABILITY, 64), CID (RECEIVE_PORT, 65), CID (SEND_PORT, 66), CID (STACK_TRACE, 67), CID (REGEXP, 68), CID (WEAK_PROPERTY, 69), CID (FUTURE_OR, 72), CID (USER_TAG, 73), CID (TRANSFERABLE_TYPED_DATA, 74), CID (ARRAY, 75), CID (IMMUTABLE_ARRAY, 76), CID (GROWABLE_OBJECT_ARRAY, 54), CID (STRING, 77), CID (ONE_BYTE_STRING, 78), CID (TWO_BYTE_STRING, 79), CID (NUM_PREDEFINED_CIDS, 148) }, 100, 142, 3 },
{ "2.14.0", { CID (ILLEGAL, 0), CID (CLASS, 4), CID (PATCH_CLASS, 5), CID (FUNCTION, 6), CID (TYPE_PARAMETERS, 7), CID (CLOSURE_DATA, 8), CID (FFI_TRAMPOLINE_DATA, 9), CID (FIELD, 10), CID (SCRIPT, 11), CID (LIBRARY, 12), CID (NAMESPACE, 13), CID (KERNEL_PROGRAM_INFO, 14), CID (WEAK_SERIALIZATION_REFERENCE, 15), CID (CODE, 16), CID (OBJECT_POOL, 20), CID (PC_DESCRIPTORS, 21), CID (CODE_SOURCE_MAP, 22), CID (COMPRESSED_STACK_MAPS, 23), CID (LOCAL_VAR_DESCRIPTORS, 24), CID (EXCEPTION_HANDLERS, 25), CID (CONTEXT, 26), CID (CONTEXT_SCOPE, 27), CID (SENTINEL, 28), CID (SINGLE_TARGET_CACHE, 29), CID (UNLINKED_CALL, 30), CID (MONOMORPHIC_SMIABLE_CALL, 31), CID (CALL_SITE_DATA, 32), CID (ICDATA, 33), CID (MEGAMORPHIC_CACHE, 34), CID (SUBTYPE_TEST_CACHE, 35), CID (LOADING_UNIT, 36), CID (API_ERROR, 38), CID (LANGUAGE_ERROR, 39), CID (UNHANDLED_EXCEPTION, 40), CID (UNWIND_ERROR, 41), CID (INSTANCE, 42), CID (LIBRARY_PREFIX, 43), CID (TYPE_ARGUMENTS, 44), CID (TYPE, 46), CID (FUNCTION_TYPE, 47), CID (TYPE_REF, 48), CID (TYPE_PARAMETER, 49), CID (CLOSURE, 50), CID (MINT, 54), CID (DOUBLE, 55), CID (FLOAT32X4, 58), CID (INT32X4, 59), CID (FLOAT64X2, 60), CID (TYPED_DATA, 62), CID (EXTERNAL_TYPED_DATA, 63), CID (TYPED_DATA_VIEW, 64), CID (CAPABILITY, 67), CID (RECEIVE_PORT, 68), CID (SEND_PORT, 69), CID (STACK_TRACE, 70), CID (REGEXP, 71), CID (WEAK_PROPERTY, 72), CID (FUTURE_OR, 74), CID (USER_TAG, 75), CID (TRANSFERABLE_TYPED_DATA, 76), CID (ARRAY, 79), CID (IMMUTABLE_ARRAY, 80), CID (GROWABLE_OBJECT_ARRAY, 57), CID (STRING, 81), CID (ONE_BYTE_STRING, 82), CID (TWO_BYTE_STRING, 83), CID (NUM_PREDEFINED_CIDS, 152) }, 104, 146, 3 },
{ "2.15.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (LOCAL_VAR_DESCRIPTORS, 25), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (API_ERROR, 39), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (UNWIND_ERROR, 42), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 48), CID (TYPE_REF, 49), CID (TYPE_PARAMETER, 50), CID (CLOSURE, 51), CID (MINT, 55), CID (DOUBLE, 56), CID (FLOAT32X4, 58), CID (INT32X4, 59), CID (FLOAT64X2, 60), CID (TYPED_DATA, 62), CID (EXTERNAL_TYPED_DATA, 63), CID (TYPED_DATA_VIEW, 64), CID (CAPABILITY, 67), CID (RECEIVE_PORT, 68), CID (SEND_PORT, 69), CID (STACK_TRACE, 70), CID (REGEXP, 71), CID (WEAK_PROPERTY, 72), CID (FUTURE_OR, 74), CID (USER_TAG, 75), CID (TRANSFERABLE_TYPED_DATA, 76), CID (ARRAY, 81), CID (IMMUTABLE_ARRAY, 82), CID (GROWABLE_OBJECT_ARRAY, 83), CID (STRING, 84), CID (ONE_BYTE_STRING, 85), CID (TWO_BYTE_STRING, 86), CID (NUM_PREDEFINED_CIDS, 154) }, 106, 148, 3 },
{ "2.16.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (LOCAL_VAR_DESCRIPTORS, 25), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (API_ERROR, 39), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (UNWIND_ERROR, 42), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 48), CID (TYPE_REF, 49), CID (TYPE_PARAMETER, 50), CID (CLOSURE, 51), CID (MINT, 55), CID (DOUBLE, 56), CID (FLOAT32X4, 58), CID (INT32X4, 59), CID (FLOAT64X2, 60), CID (TYPED_DATA, 62), CID (EXTERNAL_TYPED_DATA, 63), CID (TYPED_DATA_VIEW, 64), CID (CAPABILITY, 67), CID (RECEIVE_PORT, 68), CID (SEND_PORT, 69), CID (STACK_TRACE, 70), CID (REGEXP, 71), CID (WEAK_PROPERTY, 72), CID (FUTURE_OR, 74), CID (USER_TAG, 75), CID (TRANSFERABLE_TYPED_DATA, 76), CID (ARRAY, 81), CID (IMMUTABLE_ARRAY, 82), CID (GROWABLE_OBJECT_ARRAY, 83), CID (STRING, 84), CID (ONE_BYTE_STRING, 85), CID (TWO_BYTE_STRING, 86), CID (NUM_PREDEFINED_CIDS, 154) }, 106, 148, 3 },
{ "2.17.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (LOCAL_VAR_DESCRIPTORS, 25), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (API_ERROR, 39), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (UNWIND_ERROR, 42), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 52), CID (TYPE_REF, 53), CID (TYPE_PARAMETER, 54), CID (CLOSURE, 55), CID (MINT, 59), CID (DOUBLE, 60), CID (FLOAT32X4, 62), CID (INT32X4, 63), CID (FLOAT64X2, 64), CID (TYPED_DATA, 66), CID (EXTERNAL_TYPED_DATA, 67), CID (TYPED_DATA_VIEW, 68), CID (CAPABILITY, 71), CID (RECEIVE_PORT, 72), CID (SEND_PORT, 73), CID (STACK_TRACE, 74), CID (REGEXP, 75), CID (WEAK_PROPERTY, 76), CID (WEAK_REFERENCE, 77), CID (FUTURE_OR, 79), CID (USER_TAG, 80), CID (TRANSFERABLE_TYPED_DATA, 81), CID (ARRAY, 86), CID (IMMUTABLE_ARRAY, 87), CID (GROWABLE_OBJECT_ARRAY, 88), CID (STRING, 89), CID (ONE_BYTE_STRING, 90), CID (TWO_BYTE_STRING, 91), CID (NUM_PREDEFINED_CIDS, 158) }, 110, 152, 3 },
{ "2.18.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (LOCAL_VAR_DESCRIPTORS, 25), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (API_ERROR, 39), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (UNWIND_ERROR, 42), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 52), CID (TYPE_REF, 53), CID (TYPE_PARAMETER, 54), CID (CLOSURE, 55), CID (MINT, 59), CID (DOUBLE, 60), CID (FLOAT32X4, 62), CID (INT32X4, 63), CID (FLOAT64X2, 64), CID (TYPED_DATA, 66), CID (EXTERNAL_TYPED_DATA, 67), CID (TYPED_DATA_VIEW, 68), CID (CAPABILITY, 71), CID (RECEIVE_PORT, 72), CID (SEND_PORT, 73), CID (STACK_TRACE, 74), CID (SUSPEND_STATE, 75), CID (REGEXP, 76), CID (WEAK_PROPERTY, 77), CID (WEAK_REFERENCE, 78), CID (FUTURE_OR, 80), CID (USER_TAG, 81), CID (TRANSFERABLE_TYPED_DATA, 82), CID (MAP, 83), CID (CONST_MAP, 84), CID (SET, 85), CID (CONST_SET, 86), CID (ARRAY, 87), CID (IMMUTABLE_ARRAY, 88), CID (GROWABLE_OBJECT_ARRAY, 89), CID (STRING, 90), CID (ONE_BYTE_STRING, 91), CID (TWO_BYTE_STRING, 92), CID (NUM_PREDEFINED_CIDS, 159) }, 111, 153, 3 },
{ "2.18.2", { 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 (LOCAL_VAR_DESCRIPTORS, 27), 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 (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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 },
{ "2.18.3", { 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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (LOCAL_VAR_DESCRIPTORS, 25), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (API_ERROR, 39), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (UNWIND_ERROR, 42), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 52), CID (TYPE_REF, 53), CID (TYPE_PARAMETER, 54), CID (CLOSURE, 55), CID (MINT, 59), CID (DOUBLE, 60), CID (FLOAT32X4, 62), CID (INT32X4, 63), CID (FLOAT64X2, 64), CID (TYPED_DATA, 66), CID (EXTERNAL_TYPED_DATA, 67), CID (TYPED_DATA_VIEW, 68), CID (CAPABILITY, 71), CID (RECEIVE_PORT, 72), CID (SEND_PORT, 73), CID (STACK_TRACE, 74), CID (SUSPEND_STATE, 75), CID (REGEXP, 76), CID (WEAK_PROPERTY, 77), CID (WEAK_REFERENCE, 78), CID (FUTURE_OR, 80), CID (USER_TAG, 81), CID (TRANSFERABLE_TYPED_DATA, 82), CID (MAP, 83), CID (CONST_MAP, 84), CID (SET, 85), CID (CONST_SET, 86), CID (ARRAY, 87), CID (IMMUTABLE_ARRAY, 88), CID (GROWABLE_OBJECT_ARRAY, 89), CID (STRING, 90), CID (ONE_BYTE_STRING, 91), CID (TWO_BYTE_STRING, 92), CID (NUM_PREDEFINED_CIDS, 159) }, 111, 153, 3 },
{ "2.19.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 (CODE, 17), CID (OBJECT_POOL, 21), CID (PC_DESCRIPTORS, 22), CID (CODE_SOURCE_MAP, 23), CID (COMPRESSED_STACK_MAPS, 24), CID (LOCAL_VAR_DESCRIPTORS, 25), CID (EXCEPTION_HANDLERS, 26), CID (CONTEXT, 27), CID (CONTEXT_SCOPE, 28), CID (SENTINEL, 29), CID (SINGLE_TARGET_CACHE, 30), CID (UNLINKED_CALL, 31), CID (MONOMORPHIC_SMIABLE_CALL, 32), CID (CALL_SITE_DATA, 33), CID (ICDATA, 34), CID (MEGAMORPHIC_CACHE, 35), CID (SUBTYPE_TEST_CACHE, 36), CID (LOADING_UNIT, 37), CID (API_ERROR, 39), CID (LANGUAGE_ERROR, 40), CID (UNHANDLED_EXCEPTION, 41), CID (UNWIND_ERROR, 42), CID (INSTANCE, 43), CID (LIBRARY_PREFIX, 44), CID (TYPE_ARGUMENTS, 45), CID (TYPE, 47), CID (FUNCTION_TYPE, 48), CID (RECORD_TYPE, 49), CID (TYPE_REF, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
{ "3.0.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (LOCAL_VAR_DESCRIPTORS, 26), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (API_ERROR, 40), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (UNWIND_ERROR, 43), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_REF, 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, 177) }, 114, 170, 4 },
{ "3.1.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (LOCAL_VAR_DESCRIPTORS, 26), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (API_ERROR, 40), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (UNWIND_ERROR, 43), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
{ "3.2.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (LOCAL_VAR_DESCRIPTORS, 26), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (API_ERROR, 40), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (UNWIND_ERROR, 43), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
{ "3.3.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (LOCAL_VAR_DESCRIPTORS, 26), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (API_ERROR, 40), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (UNWIND_ERROR, 43), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 176) }, 113, 169, 4 },
{ "3.4.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (LOCAL_VAR_DESCRIPTORS, 26), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (API_ERROR, 40), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (UNWIND_ERROR, 43), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 174) }, 111, 167, 4 },
{ "3.5.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, 22), CID (PC_DESCRIPTORS, 23), CID (CODE_SOURCE_MAP, 24), CID (COMPRESSED_STACK_MAPS, 25), CID (LOCAL_VAR_DESCRIPTORS, 26), CID (EXCEPTION_HANDLERS, 27), CID (CONTEXT, 28), CID (CONTEXT_SCOPE, 29), CID (SENTINEL, 30), CID (SINGLE_TARGET_CACHE, 31), CID (UNLINKED_CALL, 32), CID (MONOMORPHIC_SMIABLE_CALL, 33), CID (CALL_SITE_DATA, 34), CID (ICDATA, 35), CID (MEGAMORPHIC_CACHE, 36), CID (SUBTYPE_TEST_CACHE, 37), CID (LOADING_UNIT, 38), CID (API_ERROR, 40), CID (LANGUAGE_ERROR, 41), CID (UNHANDLED_EXCEPTION, 42), CID (UNWIND_ERROR, 43), CID (INSTANCE, 44), CID (LIBRARY_PREFIX, 45), CID (TYPE_ARGUMENTS, 46), CID (TYPE, 48), CID (FUNCTION_TYPE, 49), CID (RECORD_TYPE, 50), CID (TYPE_PARAMETER, 51), CID (CLOSURE, 56), CID (MINT, 60), CID (DOUBLE, 61), CID (FLOAT32X4, 63), CID (INT32X4, 64), CID (FLOAT64X2, 65), CID (RECORD, 66), CID (TYPED_DATA, 68), CID (EXTERNAL_TYPED_DATA, 69), CID (TYPED_DATA_VIEW, 70), CID (CAPABILITY, 73), CID (RECEIVE_PORT, 74), CID (SEND_PORT, 75), CID (STACK_TRACE, 76), CID (SUSPEND_STATE, 77), CID (REGEXP, 78), CID (WEAK_PROPERTY, 79), CID (WEAK_REFERENCE, 80), CID (FUTURE_OR, 82), CID (USER_TAG, 83), CID (TRANSFERABLE_TYPED_DATA, 84), CID (MAP, 85), CID (CONST_MAP, 86), CID (SET, 87), CID (CONST_SET, 88), CID (ARRAY, 89), CID (IMMUTABLE_ARRAY, 90), CID (GROWABLE_OBJECT_ARRAY, 91), CID (STRING, 92), CID (ONE_BYTE_STRING, 93), CID (TWO_BYTE_STRING, 94), CID (NUM_PREDEFINED_CIDS, 174) }, 111, 167, 4 },
{ "3.6.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 (LOCAL_VAR_DESCRIPTORS, 27), CID (EXCEPTION_HANDLERS, 28), CID (CONTEXT, 29), CID (CONTEXT_SCOPE, 30), CID (SENTINEL, 31), CID (SINGLE_TARGET_CACHE, 32), CID (UNLINKED_CALL, 33), CID (MONOMORPHIC_SMIABLE_CALL, 34), CID (CALL_SITE_DATA, 35), CID (ICDATA, 36), CID (MEGAMORPHIC_CACHE, 37), CID (SUBTYPE_TEST_CACHE, 38), CID (LOADING_UNIT, 39), CID (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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.7.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 (LOCAL_VAR_DESCRIPTORS, 27), CID (EXCEPTION_HANDLERS, 28), CID (CONTEXT, 29), CID (CONTEXT_SCOPE, 30), CID (SENTINEL, 31), CID (SINGLE_TARGET_CACHE, 32), CID (UNLINKED_CALL, 33), CID (MONOMORPHIC_SMIABLE_CALL, 34), CID (CALL_SITE_DATA, 35), CID (ICDATA, 36), CID (MEGAMORPHIC_CACHE, 37), CID (SUBTYPE_TEST_CACHE, 38), CID (LOADING_UNIT, 39), CID (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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.8.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 (LOCAL_VAR_DESCRIPTORS, 27), CID (EXCEPTION_HANDLERS, 28), CID (CONTEXT, 29), CID (CONTEXT_SCOPE, 30), CID (SENTINEL, 31), CID (SINGLE_TARGET_CACHE, 32), CID (UNLINKED_CALL, 33), CID (MONOMORPHIC_SMIABLE_CALL, 34), CID (CALL_SITE_DATA, 35), CID (ICDATA, 36), CID (MEGAMORPHIC_CACHE, 37), CID (SUBTYPE_TEST_CACHE, 38), CID (LOADING_UNIT, 39), CID (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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.9.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 (LOCAL_VAR_DESCRIPTORS, 27), 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 (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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.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 (LOCAL_VAR_DESCRIPTORS, 27), 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 (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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 (LOCAL_VAR_DESCRIPTORS, 27), 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 (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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 (LOCAL_VAR_DESCRIPTORS, 27), 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 (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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 (LOCAL_VAR_DESCRIPTORS, 27), 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 (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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 (LOCAL_VAR_DESCRIPTORS, 27), 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 (API_ERROR, 41), CID (LANGUAGE_ERROR, 42), CID (UNHANDLED_EXCEPTION, 43), CID (UNWIND_ERROR, 44), 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
};
@@ -68,6 +68,7 @@ static const char *const cid_kind_names[DART_CID_KIND_COUNT] = {
[DART_CID_PC_DESCRIPTORS] = "PcDescriptors",
[DART_CID_CODE_SOURCE_MAP] = "CodeSourceMap",
[DART_CID_COMPRESSED_STACK_MAPS] = "CompressedStackMaps",
[DART_CID_LOCAL_VAR_DESCRIPTORS] = "LocalVarDescriptors",
[DART_CID_EXCEPTION_HANDLERS] = "ExceptionHandlers",
[DART_CID_CONTEXT] = "Context",
[DART_CID_CONTEXT_SCOPE] = "ContextScope",
@@ -80,8 +81,10 @@ static const char *const cid_kind_names[DART_CID_KIND_COUNT] = {
[DART_CID_MEGAMORPHIC_CACHE] = "MegamorphicCache",
[DART_CID_SUBTYPE_TEST_CACHE] = "SubtypeTestCache",
[DART_CID_LOADING_UNIT] = "LoadingUnit",
[DART_CID_API_ERROR] = "ApiError",
[DART_CID_LANGUAGE_ERROR] = "LanguageError",
[DART_CID_UNHANDLED_EXCEPTION] = "UnhandledException",
[DART_CID_UNWIND_ERROR] = "UnwindError",
[DART_CID_INSTANCE] = "Instance",
[DART_CID_LIBRARY_PREFIX] = "LibraryPrefix",
[DART_CID_TYPE_ARGUMENTS] = "TypeArguments",
+168 -14
View File
@@ -124,8 +124,61 @@ static char *make_method_flagname(const char *name) {
return flagname;
}
static void dump_func_r2(RStrBuf *sb, const DartFunction *fn, bool quiet) {
char *flagname = make_method_flagname (fn->name);
// Flag and function names are unique in r2: setting an existing flag name
// moves it, so a later function sharing a Dart name (e.g. several
// Native._anon_closure) would steal it from the first one. Suffix repeated
// names with the entry address.
static char *make_unique_method_flagname(HtPP *seen, const char *name, ut64 addr) {
char *flagname = make_method_flagname (name);
bool found = false;
ut64 owner = (ut64) (size_t)ht_pp_find (seen, flagname, &found);
if (found && owner != addr) {
char *unique = r_str_newf ("%s.0x%" PFMT64x, flagname, addr);
free (flagname);
return unique;
}
ht_pp_insert (seen, flagname, (void *) (size_t)addr);
return flagname;
}
static void method_flagname_free(HtUPKv *kv) {
free (kv->value);
}
// Map each function address to its unique method.* name, in app order.
static HtUP *method_flagnames(DartApp *app) {
HtUP *names = ht_up_new (NULL, method_flagname_free, NULL);
HtPP *seen = ht_pp_new0 ();
DartFunction *fn;
R_VEC_FOREACH (app->functions, fn) {
if (fn->name && !ht_up_find (names, fn->addr, NULL)) {
ht_up_insert (names, fn->addr, make_unique_method_flagname (seen, fn->name, fn->addr));
}
}
ht_pp_free (seen);
return names;
}
// Give each analyzed function its Dart name: r2's `af` prefers flags in the
// symbols space (e.g. Mach-O sym.func.*) over the method.* flags set here.
void dart_dumper_name_functions(DartApp *app) {
if (!app || !app->core || !app->functions) {
return;
}
HtUP *names = method_flagnames (app);
DartFunction *fn;
R_VEC_FOREACH (app->functions, fn) {
RAnalFunction *fcn = r_anal_get_function_at (app->core->anal, fn->addr);
const char *name = fcn? ht_up_find (names, fn->addr, NULL): NULL;
if (name && strcmp (fcn->name, name)) {
r_anal_function_rename (fcn, name);
}
}
ht_up_free (names);
}
static void dump_func_r2(RStrBuf *sb, HtPP *seen, const DartFunction *fn, bool quiet) {
char *flagname = make_unique_method_flagname (seen, fn->name, fn->addr);
r_strbuf_appendf (sb, "f %s = 0x%" PFMT64x "\n", flagname, (uint64_t)fn->addr);
if (!quiet) {
r_strbuf_appendf (sb, "'@0x%" PFMT64x "'CC %s\n", (uint64_t)fn->addr, fn->name);
@@ -145,13 +198,15 @@ char *dart_dumper_dump_r2(DartApp *app) {
r_strbuf_appendf (sb, "f app.heap_base = 0x%" PFMT64x "\n", (uint64_t)app->heap_base);
if (app->functions) {
HtPP *seen = ht_pp_new0 ();
DartFunction *fn;
R_VEC_FOREACH (app->functions, fn) {
if (!fn->name) {
continue;
}
dump_func_r2 (sb, fn, quiet);
dump_func_r2 (sb, seen, fn, quiet);
}
ht_pp_free (seen);
}
r_strbuf_append (sb, "dr x27=`e anal.gp`\n");
@@ -219,6 +274,7 @@ char *dart_dumper_dump_funcs(DartApp *app, int fmt) {
}
RStrBuf *sb = r_strbuf_new ("");
HtPP *seen = ht_pp_new0 ();
R_VEC_FOREACH (app->functions, fn) {
if (!fn->name) {
continue;
@@ -227,12 +283,13 @@ char *dart_dumper_dump_funcs(DartApp *app, int fmt) {
break;
}
if (fmt == 'r') {
dump_func_r2 (sb, fn, app->dctx.quiet);
dump_func_r2 (sb, seen, fn, app->dctx.quiet);
} else {
dump_func_text (sb, fn);
}
count++;
}
ht_pp_free (seen);
return drain_trimmed_strbuf (sb);
}
@@ -260,8 +317,9 @@ static void dart_type_to_c(RStrBuf *sb, const char *tok) {
}
// Turn a recovered Dart signature "RET(T,T,...)" into a radare2 `afs` prototype
// and return it, or NULL if the signature is not in that canonical form.
static char *dart_signature_to_afs_proto(const char *fname, const char *sig) {
// for the already filtered function name `name` and return it, or NULL if the
// signature is not in that canonical form.
static char *dart_signature_to_afs_proto(const char *name, const char *sig) {
if (R_STR_ISEMPTY (sig) || strchr (sig, ' ') || strchr (sig, '=')) {
return NULL; // not our canonical "RET(T,...)" form
}
@@ -279,11 +337,9 @@ static char *dart_signature_to_afs_proto(const char *fname, const char *sig) {
if (rp) {
*rp = '\0';
}
char *safe_name = strdup (fname);
r_name_filter (safe_name, 0);
RStrBuf *sb = r_strbuf_new ("");
dart_type_to_c (sb, ret);
r_strbuf_appendf (sb, " %s(", R_STR_ISNOTEMPTY (safe_name)? safe_name: "fcn");
r_strbuf_appendf (sb, " %s(", name);
int argc = 0;
if (R_STR_ISNOTEMPTY (inside)) {
RList *args = r_str_split_list (inside, ",", 0);
@@ -307,10 +363,82 @@ static char *dart_signature_to_afs_proto(const char *fname, const char *sig) {
r_strbuf_append (sb, ")");
free (ret);
free (inside);
free (safe_name);
return r_strbuf_drain (sb);
}
// Same scan as is_type() in radare2's libr/anal/type.c.
static char *dart_parsed_type_kind(char *s) {
char *p;
if ((p = strstr (s, "=type")) || (p = strstr (s, "=struct")) || (p = strstr (s, "=union")) ||
(p = strstr (s, "=enum")) || (p = strstr (s, "=typedef")) || (p = strstr (s, "=func"))) {
return p;
}
return NULL;
}
// `afs` stores a prototype with r_anal_save_parsed_type, which first calls
// r_anal_remove_parsed_type for every type the parsed C declares. When that type
// already exists, the removal r_type_del()s it and then sorts and scans the
// whole type database for leftover subkeys. For these prototypes r_type_del has
// already removed every key, so the scan finds nothing, but it cost
// O(types log types) for every repeated name (anonymous closures, and names the
// C parser shortens at ':' such as `dyn:call` -> `call`), making the signature
// pass quadratic. Deleting those types here first, with the parser `afs` uses,
// lets `afs` take its early return and leaves the same type database.
static void dart_types_predelete(RAnal *anal, const char *proto) {
Sdb *tdb = anal->sdb_types;
if (!tdb) {
return;
}
char *code = r_str_newf ("%s;", proto);
char *err = NULL;
char *parsed = r_anal_cparse (anal, code, &err);
free (code);
free (err);
if (!parsed) {
return;
}
char *cur = parsed;
while ((cur = dart_parsed_type_kind (cur))) {
char *name = cur++;
*name = 0;
while (name > parsed && *(name - 1) != '\n') {
name--;
}
if (sdb_const_get (tdb, name, 0)) {
r_type_del (tdb, name);
}
}
free (parsed);
}
static bool dart_flag_found_cb(RFlagItem *fi, void *user) {
(void)fi;
*(bool *)user = true;
return false;
}
// With anal.trycatch enabled every `af` scans all flags twice looking for
// try.<addr>.catch/filter handler flags. -AAA creates flags for every Dart
// method, string and pool reference, so across tens of thousands of functions
// those scans dominated the pass. When no try.* flag exists the scans cannot
// find a handler, so disabling the option for the pass changes nothing else.
bool dart_core_trycatch_suspend(RCore *core) {
const bool prev = r_config_get_b (core->config, "anal.trycatch");
if (prev) {
bool found = false;
r_flag_foreach_prefix (core->flags, "try.", 4, dart_flag_found_cb, &found);
if (!found) {
r_config_set_b (core->config, "anal.trycatch", false);
}
}
return prev;
}
void dart_core_trycatch_restore(RCore *core, bool prev) {
r_config_set_b (core->config, "anal.trycatch", prev);
}
static int dart_fn_addr_desc(const void *a, const void *b) {
const DartFunction *fa = *(const DartFunction *const *)a;
const DartFunction *fb = *(const DartFunction *const *)b;
@@ -348,29 +476,54 @@ void dart_dumper_apply_signatures(DartApp *app) {
}
}
qsort (order, n, sizeof (DartFunction *), dart_fn_addr_desc);
HtUP *names = method_flagnames (app);
// Keep the analysis local to each function start; the surrounding pass owns
// broader discovery. String ESIL emulation is very slow and irrelevant to
// prototypes, so disable it for the duration of this pass.
// Variable recovery, call-following and jump tables are not needed for the
// prototypes either, and var recovery alone is about half of this `af` cost.
int prev_hasnext = r_config_get_i (core->config, "anal.hasnext");
int prev_emustr = r_config_get_i (core->config, "emu.str");
bool prev_calls = r_config_get_b (core->config, "anal.calls");
bool prev_vars = r_config_get_b (core->config, "anal.vars");
bool prev_jmptbl = r_config_get_b (core->config, "anal.jmp.tbl");
r_config_set_i (core->config, "anal.hasnext", 0);
r_config_set_i (core->config, "emu.str", 0);
r_config_set_b (core->config, "anal.calls", false);
r_config_set_b (core->config, "anal.vars", false);
r_config_set_b (core->config, "anal.jmp.tbl", false);
const bool prev_trycatch = dart_core_trycatch_suspend (core);
for (size_t i = 0; i < n; i++) {
fn = order[i];
char *proto = dart_signature_to_afs_proto (fn->name? fn->name: "fcn", fn->signature);
const char *flagname = ht_up_find (names, fn->addr, NULL);
char *name = strdup (flagname? flagname: "fcn");
r_name_filter (name, 0);
if (R_STR_ISEMPTY (name)) {
free (name);
name = strdup ("fcn");
}
char *proto = dart_signature_to_afs_proto (name, fn->signature);
if (!proto) {
free (name);
continue;
}
if (!r_anal_get_function_at (core->anal, fn->addr)) {
r_core_cmdf (core, "af @ 0x%" PFMT64x, fn->addr);
}
if (r_anal_get_function_at (core->anal, fn->addr)) {
dart_types_predelete (core->anal, proto);
r_core_cmdf (core, "\"afs %s\" @ 0x%" PFMT64x, proto, fn->addr);
}
free (proto);
free (name);
}
r_config_set_i (core->config, "anal.hasnext", prev_hasnext);
r_config_set_i (core->config, "emu.str", prev_emustr);
r_config_set_b (core->config, "anal.calls", prev_calls);
r_config_set_b (core->config, "anal.vars", prev_vars);
r_config_set_b (core->config, "anal.jmp.tbl", prev_jmptbl);
dart_core_trycatch_restore (core, prev_trycatch);
ht_up_free (names);
free (order);
}
@@ -386,16 +539,17 @@ void dart_dumper_apply_to_core(DartApp *app, bool apply_signatures) {
}
if (app->functions) {
HtUP *names = method_flagnames (app);
DartFunction *fn;
R_VEC_FOREACH (app->functions, fn) {
if (!fn->name) {
const char *flagname = ht_up_find (names, fn->addr, NULL);
if (!fn->name || !flagname) {
continue;
}
char *flagname = make_method_flagname (fn->name);
r_flag_set (core->flags, flagname, fn->addr, fn->size);
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, fn->addr, fn->name);
free (flagname);
}
ht_up_free (names);
}
r_core_cmd0 (core, "e emu.str=true");
+2 -5
View File
@@ -102,11 +102,8 @@ void dart_obf_fini(DartCtx *ctx) {
ctx->obf_by_obfuscated = NULL;
ctx->obf_map_tried = false;
// Release the read_mem window cache (scoped to one command invocation).
free (ctx->rmem_cache);
ctx->rmem_cache = NULL;
ctx->rmem_cache_addr = 0;
ctx->rmem_cache_len = 0;
ctx->rmem_cache_cap = 0;
dart_read_cache_free (ctx->rmem);
ctx->rmem = NULL;
}
char *dart_obf_resolve(DartCtx *ctx, const char *name) {
+43
View File
@@ -1488,6 +1488,46 @@ static void resolve_class_and_field_names(DartCtx *ctx, RList *class_list, RList
}
}
// Function fills only carry an InstructionTable slot; decode the table once
// and turn each method's slot into its entry address.
static void resolve_method_entry_points(DartCtx *ctx, RList *class_list) {
const int dump_snapshot_json = ctx->dump_snapshot_json;
const int dump_fns_limit = ctx->dump_fns_limit;
ctx->dump_snapshot_json = 0;
ctx->dump_fns_limit = 0;
RVecDartInstructionTableEntry *it = dart_pool_extract_instruction_table (ctx);
ctx->dump_snapshot_json = dump_snapshot_json;
ctx->dump_fns_limit = dump_fns_limit;
if (!it) {
return;
}
ut64 count = 0;
DartInstructionTableEntry *ie;
R_VEC_FOREACH (it, ie) {
count = R_MAX (count, ie->index + 1);
}
// Function::code_index is the raw InstructionTable slot, not the
// first_entry_with_code-relative index kept in ie->code_index. Slots below
// first_entry_with_code lost their Code object (discarded in AOT) but
// still own real instructions, so map them too.
ut64 *addr_by_code_index = calloc (count + 1, sizeof (ut64));
R_VEC_FOREACH (it, ie) {
addr_by_code_index[ie->index] = ie->address;
}
RListIter *iter, *miter;
DartClassInfo *ci;
DartMethodInfo *mi;
r_list_foreach (class_list, iter, ci) {
r_list_foreach (ci->methods, miter, mi) {
if (!mi->entry_point && mi->code_index < count) {
mi->entry_point = addr_by_code_index[mi->code_index];
}
}
}
free (addr_by_code_index);
dart_instruction_table_list_free (it);
}
RList *dart_pool_extract_classes(DartCtx *ctx) {
if (!ctx || !ctx->core) {
return NULL;
@@ -1693,6 +1733,9 @@ RList *dart_pool_extract_classes(DartCtx *ctx) {
}
}
dart_ctx_fini_layout (ctx, layout_owned);
if (modern_classes) {
resolve_method_entry_points (ctx, class_list);
}
return class_list;
}
+492 -162
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -377,7 +377,7 @@ void collect_data_names_with_r2(DartCtx *ctx, ut64 data_image_base, ut64 data_im
continue;
}
char *line, *saveptr = NULL;
for (line = strtok_r (out, "\n", &saveptr); line; line = strtok_r (NULL, "\n", &saveptr)) {
for (line = r_str_tok_r (out, "\n", &saveptr); line; line = r_str_tok_r (NULL, "\n", &saveptr)) {
if (!r_str_startswith (line, "0x")) {
continue;
}
+3 -1
View File
@@ -460,7 +460,9 @@ static int decode_pool_and_emit(DartItEmitRequest *req) {
goto cleanup;
}
const ut64 layout_cap = ctx->layout && ctx->layout->it_cap? ctx->layout->it_cap: 20000;
const ut64 max_entries = req->max_entries > 0? req->max_entries: (req->on_it? itlen: layout_cap);
// itlen counts retained Code objects, not instructions whose Code metadata
// was discarded. Let the table header bound an unlimited IT extraction.
const ut64 max_entries = req->max_entries > 0? req->max_entries: (req->on_it? 0: layout_cap);
req->data_image_base = data_image_base;
req->data_image_end = data_image_end;
req->itlen = itlen;
+20
View File
@@ -169,6 +169,7 @@ typedef struct {
typedef struct {
ut64 pp_offset;
ut64 pp_base;
ut64 pool_ref;
ut64 pool_index;
ut64 entry_index;
@@ -177,11 +178,28 @@ typedef struct {
ut64 field_index;
ut64 string_ref;
ut64 string_addr;
ut32 string_flags;
bool via_collection;
const char *string_value;
} ModernPoolStrRef;
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,7 +292,9 @@ 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_collect_pool_value_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);
bool modern_extract_classes(const ModernReq *req, RList *classes);
+72 -40
View File
@@ -7,40 +7,81 @@
// time, so serving those reads from a prefetched window turns millions of
// r_io_read_at calls into a handful.
#define RMEM_WINDOW (1024 * 1024)
// Several windows are kept because decoders interleave distant regions, e.g.
// a cluster alloc stream and the RO data image it indexes. With a single
// window every such step refilled it twice.
#define RMEM_WINDOWS 4
typedef struct {
ut8 *buf;
ut64 addr;
ut64 used; // last access tick, for least-recently-used eviction
int len;
} DartReadWindow;
typedef struct dart_read_cache_t {
DartReadWindow w[RMEM_WINDOWS];
ut64 tick;
} DartReadCache;
void dart_read_cache_free(DartReadCache *cache) {
if (!cache) {
return;
}
for (int i = 0; i < RMEM_WINDOWS; i++) {
free (cache->w[i].buf);
}
free (cache);
}
bool read_mem(DartCtx *ctx, ut64 addr, void *buf, int len) {
if (!ctx || !ctx->core || !buf || len <= 0) {
return false;
}
// Fast path: request fully contained in the cached window.
if (ctx->rmem_cache && addr >= ctx->rmem_cache_addr) {
ut64 off = addr - ctx->rmem_cache_addr;
if (off + (ut64)len <= (ut64)ctx->rmem_cache_len) {
memcpy (buf, ctx->rmem_cache + off, (size_t)len);
return true;
}
}
// Reads larger than the window bypass the cache.
// Reads larger than a window bypass the cache.
if (len > RMEM_WINDOW) {
return r_io_read_at (ctx->core->io, addr, (ut8 *)buf, len);
}
if (!ctx->rmem_cache) {
ctx->rmem_cache = malloc (RMEM_WINDOW);
if (!ctx->rmem_cache) {
if (!ctx->rmem) {
ctx->rmem = R_NEW0 (DartReadCache);
}
DartReadCache *cache = ctx->rmem;
cache->tick++;
// Fast path: request fully contained in a cached window.
DartReadWindow *victim = &cache->w[0];
for (int i = 0; i < RMEM_WINDOWS; i++) {
DartReadWindow *w = &cache->w[i];
if (w->len && addr >= w->addr) {
ut64 off = addr - w->addr;
if (off + (ut64)len <= (ut64)w->len) {
w->used = cache->tick;
memcpy (buf, w->buf + off, (size_t)len);
return true;
}
}
if (w->used < victim->used) {
victim = w;
}
}
if (!victim->buf) {
victim->buf = malloc (RMEM_WINDOW);
if (!victim->buf) {
return r_io_read_at (ctx->core->io, addr, (ut8 *)buf, len);
}
ctx->rmem_cache_cap = RMEM_WINDOW;
}
// Refill the window at addr. r_io_read_at only succeeds when the whole
// range is readable, so a successful window read means every byte in it is
// valid and safe to serve. On failure (e.g. near the end of a mapped
// region) fall back to an exact read and keep any previous window intact.
if (r_io_read_at (ctx->core->io, addr, ctx->rmem_cache, ctx->rmem_cache_cap)) {
ctx->rmem_cache_addr = addr;
ctx->rmem_cache_len = ctx->rmem_cache_cap;
memcpy (buf, ctx->rmem_cache, (size_t)len);
// Refill the least recently used window at addr. r_io_read_at only
// succeeds when the whole range is readable, so a successful window read
// means every byte in it is valid and safe to serve. On failure (e.g. near
// the end of a mapped region) fall back to an exact read and drop that
// window, whose buffer the failed read may have clobbered.
if (r_io_read_at (ctx->core->io, addr, victim->buf, RMEM_WINDOW)) {
victim->addr = addr;
victim->len = RMEM_WINDOW;
victim->used = cache->tick;
memcpy (buf, victim->buf, (size_t)len);
return true;
}
victim->len = 0;
return r_io_read_at (ctx->core->io, addr, (ut8 *)buf, len);
}
@@ -442,33 +483,24 @@ bool cs_read_tagged32(ClusterStream *s, ut32 *out) {
return false;
}
// ReadStream::Read<int64_t>: 7-bit groups, then a final byte holding a signed
// value in [-64, 63] biased by kEndByteMarker (192).
bool cs_read_tagged64(ClusterStream *s, int64_t *out) {
ut8 raw = 0;
if (!cs_read_u8 (s, &raw)) {
return false;
}
int8_t b = (int8_t)raw;
if (b < 0) {
if (out) {
*out = (int64_t)b + 192;
}
return true;
}
int64_t v = (int64_t)raw;
int shift = 7;
for (int i = 1; i < 10; i++) {
ut64 v = 0;
int shift = 0;
for (int i = 0; i < 10; i++) {
ut8 raw = 0;
if (!cs_read_u8 (s, &raw)) {
return false;
}
b = (int8_t)raw;
if (b < 0) {
v |= ((int64_t)b + 192) << shift;
if (raw > 0x7f) {
v |= (ut64) ((int64_t)raw - 192) << shift;
if (out) {
*out = v;
*out = (int64_t)v;
}
return true;
}
v |= ((int64_t)raw) << shift;
v |= (ut64)raw << shift;
shift += 7;
}
return false;
+110 -74
View File
@@ -26,7 +26,17 @@ void dart_string_list_free(RList *list) {
r_list_free (list);
}
#define DART_STRING_SCAN_LIMIT 50000
typedef struct {
RList *list;
HtUP *seen_addrs;
ut64 ref_counter;
ut64 limit; // 0 means unlimited
} StringScan;
static bool string_scan_full(const StringScan *ss) {
return ss->limit && (ut64)r_list_length (ss->list) >= ss->limit;
}
DartStringCategory dart_string_classify_value(const char *s) {
if (R_STR_ISEMPTY (s)) {
return DART_STRING_CAT_UNKNOWN;
@@ -57,7 +67,7 @@ static const char *string_category_name(DartStringCategory cat) {
}
}
static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter);
static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, StringScan *ss);
static bool should_scan_section(const RBinSection *sec);
static bool is_common_text_punct(ut8 ch) {
@@ -146,31 +156,28 @@ static void packed_string_record_fini(PackedStringRecord *rec) {
rec->value = NULL;
}
static void append_string_info(RList *list, HtUP *seen_addrs, const char *value, ut32 len, ut32 flags, ut64 addr, DartStringCategory cat, ut64 *ref_counter) {
if (!list || !value) {
static void append_string_info(StringScan *ss, const char *value, ut32 len, ut32 flags, ut64 addr, DartStringCategory cat) {
if (!value || string_scan_full (ss)) {
return;
}
if (r_list_length (list) >= DART_STRING_SCAN_LIMIT) {
return;
}
if (seen_addrs && addr && ht_up_find (seen_addrs, addr, NULL)) {
if (addr && ht_up_find (ss->seen_addrs, addr, NULL)) {
return;
}
DartStringInfo *si = R_NEW0 (DartStringInfo);
si->ref_id = ref_counter? (*ref_counter)++: 0;
si->ref_id = ss->ref_counter++;
si->length = len;
si->flags = flags | DART_STRING_CANONICAL;
si->address = addr;
si->category = cat;
si->references = r_list_newf ((RListFree)dart_string_ref_free);
si->value = strdup (value);
r_list_append (list, si);
if (seen_addrs && addr) {
ht_up_insert (seen_addrs, addr, si);
r_list_append (ss->list, si);
if (addr) {
ht_up_insert (ss->seen_addrs, addr, si);
}
}
static void scan_ascii_strings(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) {
static void scan_ascii_strings(const ut8 *buf, ut64 base, ut64 size, StringScan *ss) {
if (!buf || !size) {
return;
}
@@ -190,7 +197,7 @@ static void scan_ascii_strings(const ut8 *buf, ut64 base, ut64 size, RList *list
memcpy (tmp, buf + start, length);
tmp[length] = '\0';
if (looks_like_text (tmp)) {
append_string_info (list, seen_addrs, tmp, (ut32)length, 0, base + start, dart_string_classify_value (tmp), ref_counter);
append_string_info (ss, tmp, (ut32)length, 0, base + start, dart_string_classify_value (tmp));
}
free (tmp);
}
@@ -334,12 +341,12 @@ static bool parse_packed_string_record_text(const ut8 *buf, ut64 size, ut64 pos,
return out->value != NULL;
}
static void scan_packed_string_runs(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) {
if (!buf || !size || !list) {
static void scan_packed_string_runs(const ut8 *buf, ut64 base, ut64 size, StringScan *ss) {
if (!buf || !size) {
return;
}
ut64 pos = 0;
while (pos < size && r_list_length (list) < DART_STRING_SCAN_LIMIT) {
while (pos < size && !string_scan_full (ss)) {
PackedStringRecord probe = { 0 };
if (!parse_packed_string_record_text (buf, size, pos, &probe)) {
pos++;
@@ -372,9 +379,9 @@ static void scan_packed_string_runs(const ut8 *buf, ut64 base, ut64 size, RList
skips++;
}
if (n_records >= DART_PACKED_STRING_MIN_RUN) {
for (int i = 0; i < n_records && r_list_length (list) < DART_STRING_SCAN_LIMIT; i++) {
for (int i = 0; i < n_records && !string_scan_full (ss); i++) {
PackedStringRecord *rec = &records[i];
append_string_info (list, seen_addrs, rec->value, rec->length, rec->flags, base + rec->payload_off, dart_string_classify_value (rec->value), ref_counter);
append_string_info (ss, rec->value, rec->length, rec->flags, base + rec->payload_off, dart_string_classify_value (rec->value));
}
pos = run_end;
} else {
@@ -386,8 +393,8 @@ static void scan_packed_string_runs(const ut8 *buf, ut64 base, ut64 size, RList
}
}
static void scan_packed_strings_from_snapshot(DartCtx *ctx, ut64 snapshot_base, RList *list, HtUP *seen_addrs, ut64 *ref_counter) {
if (!ctx || !snapshot_base || !list) {
static void scan_packed_strings_from_snapshot(DartCtx *ctx, ut64 snapshot_base, StringScan *ss) {
if (!ctx || !snapshot_base) {
return;
}
ut8 hdrbuf[12];
@@ -417,23 +424,23 @@ static void scan_packed_strings_from_snapshot(DartCtx *ctx, ut64 snapshot_base,
if (ctx->verbose > 1) {
fprintf (stderr, "[r2flutter] packed string scan snapshot=0x%" PFMT64x " cluster_start=0x%" PFMT64x " total=0x%" PFMT64x "\n", snapshot_base, snapshot_base + hdr.cluster_start, hdr.total_len);
}
scan_packed_string_runs (buf + hdr.cluster_start, snapshot_base + hdr.cluster_start, hdr.total_len - hdr.cluster_start, list, seen_addrs, ref_counter);
scan_packed_string_runs (buf + hdr.cluster_start, snapshot_base + hdr.cluster_start, hdr.total_len - hdr.cluster_start, ss);
free (buf);
}
#define DART_SNAPSHOT_SCAN_MAX (64ULL << 20)
#define DART_DATA_IMAGE_SCAN_MAX (8ULL << 20)
static void scan_string_buffer(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) {
if (!buf || !size || !list) {
static void scan_string_buffer(const ut8 *buf, ut64 base, ut64 size, StringScan *ss) {
if (!buf || !size) {
return;
}
scan_ascii_strings (buf, base, size, list, seen_addrs, ref_counter);
scan_utf16_strings (buf, base, size, list, seen_addrs, ref_counter);
scan_ascii_strings (buf, base, size, ss);
scan_utf16_strings (buf, base, size, ss);
}
static void scan_snapshot_region(DartCtx *ctx, ut64 start, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) {
if (!ctx || !ctx->core || !ctx->core->bin || !start || !size || !list || size > DART_SNAPSHOT_SCAN_MAX) {
static void scan_snapshot_region(DartCtx *ctx, ut64 start, ut64 size, StringScan *ss) {
if (!ctx || !ctx->core || !ctx->core->bin || !start || !size || size > DART_SNAPSHOT_SCAN_MAX) {
return;
}
ut64 end = start + size;
@@ -468,16 +475,16 @@ static void scan_snapshot_region(DartCtx *ctx, ut64 start, ut64 size, RList *lis
free (buf);
continue;
}
scan_string_buffer (buf, chunk_start, chunk_size, list, seen_addrs, ref_counter);
scan_string_buffer (buf, chunk_start, chunk_size, ss);
free (buf);
}
}
static void scan_strings_from_snapshot_window(DartCtx *ctx, ut64 snapshot_base, ut64 upper_bound, RList *list, HtUP *seen_addrs, ut64 *ref_counter) {
if (!ctx || !snapshot_base || !list) {
static void scan_strings_from_snapshot_window(DartCtx *ctx, ut64 snapshot_base, ut64 upper_bound, StringScan *ss) {
if (!ctx || !snapshot_base) {
return;
}
ut64 before_count = r_list_length (list);
ut64 before_count = r_list_length (ss->list);
DartSnapshotHeader sh;
if (!dart_snapshot_header_read (ctx, snapshot_base, &sh)) {
goto fallback;
@@ -486,10 +493,10 @@ static void scan_strings_from_snapshot_window(DartCtx *ctx, ut64 snapshot_base,
goto fallback;
}
if (ctx->compressed_word_size == 4) {
scan_packed_strings_from_snapshot (ctx, snapshot_base, list, seen_addrs, ref_counter);
scan_packed_strings_from_snapshot (ctx, snapshot_base, ss);
return;
}
scan_snapshot_region (ctx, snapshot_base + sh.cluster_start, sh.total_len - sh.cluster_start, list, seen_addrs, ref_counter);
scan_snapshot_region (ctx, snapshot_base + sh.cluster_start, sh.total_len - sh.cluster_start, ss);
ut64 align = ctx->layout && ctx->layout->max_alignment? (ut64)ctx->layout->max_alignment: 16;
if (align == 0) {
align = 16;
@@ -497,18 +504,18 @@ static void scan_strings_from_snapshot_window(DartCtx *ctx, ut64 snapshot_base,
ut64 data_start = snapshot_base + ((sh.total_len + (align - 1)) & ~ (align - 1));
ut64 data_end = upper_bound;
if (data_end > data_start && (data_end - data_start) <= DART_DATA_IMAGE_SCAN_MAX) {
scan_snapshot_region (ctx, data_start, data_end - data_start, list, seen_addrs, ref_counter);
scan_snapshot_region (ctx, data_start, data_end - data_start, ss);
}
if ((ut64)r_list_length (list) > before_count) {
if ((ut64)r_list_length (ss->list) > before_count) {
return;
}
fallback:
if (upper_bound > snapshot_base + 0x100 && (upper_bound - (snapshot_base + 0x100)) <= DART_DATA_IMAGE_SCAN_MAX) {
scan_snapshot_region (ctx, snapshot_base + 0x100, upper_bound - (snapshot_base + 0x100), list, seen_addrs, ref_counter);
scan_snapshot_region (ctx, snapshot_base + 0x100, upper_bound - (snapshot_base + 0x100), ss);
}
}
static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) {
static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, StringScan *ss) {
if (!buf || size < 8) {
return;
}
@@ -536,7 +543,7 @@ static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, RList *list
if (utf8 && units >= 4 && utf16le_has_ascii_profile (buf, start, start + (units * 2))) {
ut32 ulen = (ut32)strlen (utf8);
if (ulen >= 4 && ulen <= 512 && looks_like_text (utf8)) {
append_string_info (list, seen_addrs, utf8, ulen, DART_STRING_TWO_BYTE, base + start, dart_string_classify_value (utf8), ref_counter);
append_string_info (ss, utf8, ulen, DART_STRING_TWO_BYTE, base + start, dart_string_classify_value (utf8));
}
}
r_strbuf_fini (&sb);
@@ -583,16 +590,15 @@ RList *dart_pool_extract_strings(DartCtx *ctx) {
return NULL;
}
RList *string_list = r_list_newf ((RListFree)dart_string_info_free);
HtUP *seen_addrs = ht_up_new0 ();
if (!seen_addrs) {
return string_list;
}
RVecRBinSection *sections = r_bin_get_sections_vec (ctx->core->bin);
if (!sections) {
ht_up_free (seen_addrs);
return string_list;
}
ut64 ref_counter = 0;
StringScan ss = {
.list = string_list,
.seen_addrs = ht_up_new0 (),
.limit = ctx->str_scan_limit
};
if (find_snapshots (ctx) == 0 && ctx->vm_data) {
DartVerLayout layout_tmp;
DartVerLayout *layout_owned = dart_ctx_init_layout (ctx, &layout_tmp);
@@ -608,14 +614,14 @@ RList *dart_pool_extract_strings(DartCtx *ctx) {
} else if (ctx->iso_instr > ctx->iso_data) {
iso_upper = ctx->iso_instr;
}
scan_strings_from_snapshot_window (ctx, ctx->vm_data, vm_upper, string_list, seen_addrs, &ref_counter);
scan_strings_from_snapshot_window (ctx, ctx->iso_data, iso_upper, string_list, seen_addrs, &ref_counter);
scan_strings_from_snapshot_window (ctx, ctx->vm_data, vm_upper, &ss);
scan_strings_from_snapshot_window (ctx, ctx->iso_data, iso_upper, &ss);
if (r_list_length (string_list) == 0) {
if (vm_upper > ctx->vm_data + 0x100) {
scan_snapshot_region (ctx, ctx->vm_data + 0x100, vm_upper - (ctx->vm_data + 0x100), string_list, seen_addrs, &ref_counter);
scan_snapshot_region (ctx, ctx->vm_data + 0x100, vm_upper - (ctx->vm_data + 0x100), &ss);
}
if (iso_upper > ctx->iso_data + 0x100) {
scan_snapshot_region (ctx, ctx->iso_data + 0x100, iso_upper - (ctx->iso_data + 0x100), string_list, seen_addrs, &ref_counter);
scan_snapshot_region (ctx, ctx->iso_data + 0x100, iso_upper - (ctx->iso_data + 0x100), &ss);
}
}
dart_ctx_fini_layout (ctx, layout_owned);
@@ -637,9 +643,9 @@ RList *dart_pool_extract_strings(DartCtx *ctx) {
free (buf);
continue;
}
scan_string_buffer (buf, sec->vaddr, size, string_list, seen_addrs, &ref_counter);
scan_string_buffer (buf, sec->vaddr, size, &ss);
free (buf);
if (r_list_length (string_list) >= DART_STRING_SCAN_LIMIT) {
if (string_scan_full (&ss)) {
break;
}
}
@@ -648,12 +654,12 @@ RList *dart_pool_extract_strings(DartCtx *ctx) {
if (size > 0 && size <= DART_SNAPSHOT_SCAN_MAX) {
ut8 *buf = (ut8 *)malloc ((size_t)size);
if (buf && read_mem (ctx, 0, buf, (int)size)) {
scan_string_buffer (buf, 0, size, string_list, seen_addrs, &ref_counter);
scan_string_buffer (buf, 0, size, &ss);
}
free (buf);
}
}
ht_up_free (seen_addrs);
ht_up_free (ss.seen_addrs);
r_list_sort (string_list, (RListComparator)string_info_addr_cmp);
return string_list;
}
@@ -832,36 +838,62 @@ static void dump_string_text(RStrBuf *sb, const DartStringInfo *si, int fmt, boo
}
}
static bool string_matches(const DartCtx *ctx, const RRegex *rx, const DartStringInfo *si) {
if (!si || !si->value) {
return false;
}
if (ctx->str_minlen > 0 && si->length < (ut32)ctx->str_minlen) {
return false;
}
if (ctx->str_maxlen > 0 && si->length > (ut32)ctx->str_maxlen) {
return false;
}
return !rx || r_regex_exec (rx, si->value, 0, NULL, 0) == 0;
}
static char *dump_strings_list(DartCtx *ctx, RList *strings, int fmt) {
const bool refs = ctx && ctx->dump_string_refs;
RRegex *rx = NULL;
if (R_STR_ISNOTEMPTY (ctx->str_filter)) {
rx = r_regex_new (ctx->str_filter, "e");
if (!rx) {
R_LOG_ERROR ("Invalid string filter regex: %s", ctx->str_filter);
return NULL;
}
}
const bool refs = ctx->dump_string_refs;
const bool quiet = ctx->quiet;
PJ *pj = NULL;
RStrBuf *sb = NULL;
if (fmt == 'j') {
if (!strings || r_list_length (strings) == 0) {
return strdup ("[]");
}
PJ *pj = pj_new ();
pj = pj_new ();
pj_a (pj);
RListIter *it;
DartStringInfo *si;
r_list_foreach (strings, it, si) {
if (si) {
dump_string_json (pj, si, refs);
}
}
pj_end (pj);
return pj_drain (pj);
} else {
sb = r_strbuf_new (fmt == 'r' && !quiet? "# Dart Strings\n": "");
}
if (!strings) {
return strdup ("# No strings found\n");
}
const bool quiet = ctx && ctx->quiet;
RStrBuf *sb = r_strbuf_new (fmt == 'r' && !quiet? "# Dart Strings\n": "");
ut64 count = 0;
RListIter *it;
DartStringInfo *si;
r_list_foreach (strings, it, si) {
dump_string_text (sb, si, fmt, quiet, refs);
if (ctx->str_limit && count >= ctx->str_limit) {
break;
}
if (!string_matches (ctx, rx, si)) {
continue;
}
if (pj) {
dump_string_json (pj, si, refs);
} else {
dump_string_text (sb, si, fmt, quiet, refs);
}
count++;
}
r_regex_free (rx);
if (pj) {
pj_end (pj);
return pj_drain (pj);
}
if (fmt == 'r' && !quiet) {
r_strbuf_appendf (sb, "# Total: %d strings\n", r_list_length (strings));
r_strbuf_appendf (sb, "# Total: %" PFMT64u " strings\n", count);
}
return r_strbuf_drain (sb);
}
@@ -874,8 +906,12 @@ char *dart_pool_dump_strings(DartCtx *ctx, int fmt) {
}
char *dart_pool_dump_strings_fuzzy(DartCtx *ctx, int fmt) {
// stop carving early only when every scanned string is going to be printed
const bool filtered = ctx->str_minlen > 0 || ctx->str_maxlen > 0 || R_STR_ISNOTEMPTY (ctx->str_filter);
ctx->str_scan_limit = filtered? 0: ctx->str_limit;
DartRecoveryModel model = { 0 };
dart_recovery_model_load (ctx, &model, DART_RECOVERY_STRINGS | DART_RECOVERY_CLASSES | DART_RECOVERY_STRING_REFS);
ctx->str_scan_limit = 0;
char *out = dump_strings_list (ctx, model.strings, fmt);
dart_recovery_model_fini (&model);
return out;
+77 -50
View File
@@ -33,7 +33,7 @@ typedef struct {
typedef struct {
DartCtx *ctx;
RList *buckets;
HtUP *buckets;
RList *xrefs;
ut64 *count;
ut64 limit;
@@ -498,30 +498,20 @@ static const char *xref_pool_flag_kind(const char *name, const char **dst_type,
return NULL;
}
static bool xref_pool_use_seen(HtUP *seen, ut64 at, ut64 pp_off) {
ut64 key = at ^ (pp_off << 8) ^ (pp_off >> 8);
if (ht_up_find (seen, key, NULL)) {
static bool xref_pool_use_seen(HtUP *seen, ut64 at) {
// Each instruction contributes at most one PP use. Key by its address so
// distinct sites cannot collide through a lossy address/offset combination.
if (ht_up_find (seen, at, NULL)) {
return true;
}
ht_up_insert (seen, key, (void *)1);
ht_up_insert (seen, at, (void *)1);
return false;
}
#define DART_XREF_MAX_OPS 96
// `end_addr` is the next entry's address, or 0 when unknown. Without it the
// scan disassembles a fixed window that runs past short functions into their
// neighbours, crediting those neighbours' pool references to this entry.
// `end_addr` is the next entry's address, or the instructions-image end for
// the last entry. Scan the whole payload without crossing into its neighbour.
static void collect_pool_uses_from_entry(DartCtx *ctx, const DartInstructionTableEntry *entry, ut64 end_addr, RList *uses, HtUP *seen) {
if (!ctx || !ctx->core || !entry || !entry->address || !uses || !seen) {
return;
}
ut64 nops = DART_XREF_MAX_OPS;
if (end_addr > entry->address) {
const ut64 avail = (end_addr - entry->address) / 4;
nops = R_MIN (avail, (ut64)DART_XREF_MAX_OPS);
}
if (!nops) {
if (!ctx || !ctx->core || !entry || !entry->address || end_addr <= entry->address || !uses || !seen) {
return;
}
// Decode the function's instructions one at a time via r_core_anal_op and
@@ -531,9 +521,9 @@ static void collect_pool_uses_from_entry(DartCtx *ctx, const DartInstructionTabl
bool reg_valid[31] = { false };
ut64 reg_off[31] = { 0 };
ut64 at = entry->address;
for (ut64 i = 0; i < nops; i++) {
while (at < end_addr) {
RAnalOp *op = r_core_anal_op (ctx->core, at, R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_DISASM);
if (!op || op->size <= 0 || R_STR_ISEMPTY (op->mnemonic)) {
if (!op || op->size <= 0 || (ut64)op->size > end_addr - at || R_STR_ISEMPTY (op->mnemonic)) {
r_anal_op_free (op);
break;
}
@@ -541,7 +531,7 @@ static void collect_pool_uses_from_entry(DartCtx *ctx, const DartInstructionTabl
ut64 pp_off = 0;
bool have_pp = xref_parse_pp_offset (m, &pp_off) ||
xref_parse_mem_pp_offset (m, reg_valid, reg_off, &pp_off);
if (have_pp && !xref_pool_use_seen (seen, at, pp_off)) {
if (have_pp && !xref_pool_use_seen (seen, at)) {
DartPoolUseInfo *ui = R_NEW0 (DartPoolUseInfo);
ui->at = at;
ui->fn_index = entry->index;
@@ -565,35 +555,40 @@ static void collect_pool_uses_from_entry(DartCtx *ctx, const DartInstructionTabl
}
}
static RList *collect_pool_uses(DartCtx *ctx, RVecDartInstructionTableEntry *entries, ut64 limit) {
static ut64 xref_instructions_end(DartCtx *ctx) {
ut64 size = 0;
if (find_snapshots (ctx) != 0 || !ctx->iso_instr || !read_u64_at (ctx, ctx->iso_instr, &size) || size < DART_IMAGE_ALIGNMENT || size > UT64_MAX - ctx->iso_instr) {
return 0;
}
const ut64 end = ctx->iso_instr + size;
RIOMap *map = r_io_map_get_at (ctx->core->io, ctx->iso_instr);
return map && end - 1 <= r_io_map_to (map)? end: 0;
}
static RList *collect_pool_uses(DartCtx *ctx, RVecDartInstructionTableEntry *entries) {
RList *uses = r_list_newf (dart_pool_use_info_free);
if (!ctx || !entries || RVecDartInstructionTableEntry_length (entries) == 0) {
return uses;
}
HtUP *seen = ht_up_new0 ();
ut64 scanned = 0;
ut64 scan_limit = limit > 0? limit: 4096;
const ut64 image_end = xref_instructions_end (ctx);
const ut64 nentries = RVecDartInstructionTableEntry_length (entries);
for (ut64 i = 0; i < nentries; i++) {
const DartInstructionTableEntry *entry = RVecDartInstructionTableEntry_at (entries, i);
if (!entry || !entry->has_code || !entry->address) {
if (!entry || !entry->address) {
continue;
}
if (scan_limit > 0 && scanned >= scan_limit) {
break;
}
// Entries are emitted in ascending address order, so the next one with
// code bounds this one.
ut64 end_addr = 0;
// a distinct address bounds this one, including discarded-Code entries.
ut64 end_addr = image_end;
for (ut64 k = i + 1; k < nentries; k++) {
const DartInstructionTableEntry *nx = RVecDartInstructionTableEntry_at (entries, k);
if (nx && nx->address > entry->address) {
end_addr = nx->address;
end_addr = image_end? R_MIN (image_end, nx->address): nx->address;
break;
}
}
collect_pool_uses_from_entry (ctx, entry, end_addr, uses, seen);
scanned++;
}
ht_up_free (seen);
return uses;
@@ -653,17 +648,6 @@ static bool resolve_pool_entry_xref(DartCtx *ctx, DartRecoveryModel *model, RLis
return false;
}
static DartPpUseBucket *xref_bucket_by_pp(RList *buckets, ut64 pp_off) {
RListIter *it;
DartPpUseBucket *bucket;
r_list_foreach (buckets, it, bucket) {
if (bucket && bucket->pp_off == pp_off) {
return bucket;
}
}
return NULL;
}
static void xref_serialized_pool_string_cb(const ModernPoolStrRef *info, void *user) {
DartSerializedPoolXrefCtx *ux = (DartSerializedPoolXrefCtx *)user;
if (!info || !ux || !ux->buckets || !ux->xrefs || !ux->count || xref_limit_reached (*ux->count, ux->limit)) {
@@ -672,7 +656,7 @@ static void xref_serialized_pool_string_cb(const ModernPoolStrRef *info, void *u
if (!info->string_addr || R_STR_ISEMPTY (info->string_value)) {
return;
}
DartPpUseBucket *bucket = xref_bucket_by_pp (ux->buckets, info->pp_offset);
DartPpUseBucket *bucket = ht_up_find (ux->buckets, info->pp_offset, NULL);
if (!bucket || !bucket->uses) {
return;
}
@@ -701,13 +685,13 @@ static bool collect_serialized_object_pool_xrefs(DartCtx *ctx, RList *uses, RLis
if (!use) {
continue;
}
DartPpUseBucket *bucket = xref_bucket_by_pp (buckets, use->pp_off);
DartPpUseBucket *bucket = ht_up_find (wanted, use->pp_off, NULL);
if (!bucket) {
bucket = R_NEW0 (DartPpUseBucket);
bucket->pp_off = use->pp_off;
bucket->uses = r_list_new ();
r_list_append (buckets, bucket);
ht_up_insert (wanted, use->pp_off, (void *)1);
ht_up_insert (wanted, use->pp_off, bucket);
}
r_list_append (bucket->uses, use);
}
@@ -715,7 +699,7 @@ static bool collect_serialized_object_pool_xrefs(DartCtx *ctx, RList *uses, RLis
DartVerLayout *layout_owned = ctx->layout? NULL: dart_ctx_init_layout (ctx, &layout_tmp);
DartSerializedPoolXrefCtx ux = {
.ctx = ctx,
.buckets = buckets,
.buckets = wanted,
.xrefs = xrefs,
.count = count,
.limit = limit,
@@ -752,7 +736,7 @@ static void collect_object_pool_xrefs(DartCtx *ctx, DartRecoveryModel *model, RL
if (!ctx || !ctx->core || !model || !model->it_entries || !xrefs || xref_limit_reached (*count, limit)) {
return;
}
RList *uses = collect_pool_uses (ctx, model->it_entries, limit);
RList *uses = collect_pool_uses (ctx, model->it_entries);
(void)collect_serialized_object_pool_xrefs (ctx, uses, xrefs, count, limit);
ut64 pool_base = xref_object_pool_base (ctx);
if (!pool_base) {
@@ -784,7 +768,11 @@ static RList *dart_pool_extract_xrefs(DartCtx *ctx) {
const ut64 limit = ctx->dump_fns_limit > 0? (ut64)ctx->dump_fns_limit: 0;
ut64 count = 0;
DartRecoveryModel model = { 0 };
dart_recovery_model_load (ctx, &model, DART_RECOVERY_STRINGS | DART_RECOVERY_CLASSES | DART_RECOVERY_CLASS_FIELDS | DART_RECOVERY_IT);
dart_recovery_model_load (ctx, &model, DART_RECOVERY_STRINGS | DART_RECOVERY_CLASSES | DART_RECOVERY_CLASS_FIELDS);
// Even limited output needs the full table to bound every scanned payload.
DartCtx work = *ctx;
work.dump_fns_limit = 0;
model.it_entries = dart_pool_extract_instruction_table (&work);
RList *classes = model.classes;
RVecDartInstructionTableEntry *it_entries = model.it_entries;
if (classes) {
@@ -1015,3 +1003,42 @@ char *dart_pool_dump_xrefs(DartCtx *ctx, int fmt) {
}
return out;
}
// Apply the recovered xref graph to the RCore as real r2 xrefs. Unlike the
// analysis disassembly scan, which only sees loads inside functions, this also
// surfaces references that live in the data image (e.g. a const object in
// .rodata pointing at a string), so `axt` resolves pool-referenced strings that
// no instruction loads directly. Returns the number of xrefs applied.
int dart_pool_apply_xrefs(DartCtx *ctx) {
if (!ctx || !ctx->core || !ctx->core->anal) {
return 0;
}
// The reliable ObjectPool strings carry their reference sites (source_addr),
// including references that live in the data image (e.g. a const object in
// .rodata pointing at the string). The analysis disassembly scan only sees
// loads inside functions, so without this `axt <string>` is empty for
// strings no instruction loads directly.
RList *strings = dart_pool_extract_pool_strings (ctx);
if (!strings) {
return 0;
}
int applied = 0;
RListIter *it;
DartStringInfo *si;
r_list_foreach (strings, it, si) {
if (!si || !si->address || !si->references) {
continue;
}
RListIter *rit;
DartStringRef *sr;
r_list_foreach (si->references, rit, sr) {
if (!sr || sr->source_addr == 0) {
continue;
}
r_anal_xrefs_set (ctx->core->anal, sr->source_addr, si->address, R_ANAL_REF_TYPE_STRN | R_ANAL_REF_TYPE_READ);
applied++;
}
}
dart_string_list_free (strings);
return applied;
}
+1 -1
View File
@@ -359,7 +359,7 @@ static void sbom_scan_pubspec_lock(RList *components, const char *path) {
bool in_packages = false;
char *current = NULL;
char *saveptr = NULL;
for (char *line = strtok_r (yaml, "\n", &saveptr); line; line = strtok_r (NULL, "\n", &saveptr)) {
for (char *line = r_str_tok_r (yaml, "\n", &saveptr); line; line = r_str_tok_r (NULL, "\n", &saveptr)) {
if (!strcmp (line, "packages:")) {
in_packages = true;
continue;
+40 -2
View File
@@ -12,6 +12,10 @@
#define R2FLUTTER_CFG_MAPFILE "r2flutter.mapfile"
#define R2FLUTTER_CFG_NAMEPOOL "r2flutter.namepool"
#define R2FLUTTER_CFG_PROFILE "r2flutter.profile"
#define R2FLUTTER_CFG_STR_LIMIT "r2flutter.str.limit"
#define R2FLUTTER_CFG_STR_MINLEN "r2flutter.str.minlen"
#define R2FLUTTER_CFG_STR_MAXLEN "r2flutter.str.maxlen"
#define R2FLUTTER_CFG_STR_FILTER "r2flutter.str.filter"
typedef struct {
char action;
@@ -36,6 +40,14 @@ static bool r2flutter_core_init(RCorePluginSession *cps) {
r_config_node_desc (node, "Enable heuristic name-pool fallback resolution");
node = r_config_set (cfg, R2FLUTTER_CFG_PROFILE, "");
r_config_node_desc (node, "Override Dart snapshot profile by 32-byte hash or Dart version");
node = r_config_set_i (cfg, R2FLUTTER_CFG_STR_LIMIT, 0);
r_config_node_desc (node, "Maximum number of strings to print (0 = unlimited)");
node = r_config_set_i (cfg, R2FLUTTER_CFG_STR_MINLEN, 0);
r_config_node_desc (node, "Skip printing strings shorter than this length");
node = r_config_set_i (cfg, R2FLUTTER_CFG_STR_MAXLEN, 0);
r_config_node_desc (node, "Skip printing strings longer than this length (0 = unlimited)");
node = r_config_set (cfg, R2FLUTTER_CFG_STR_FILTER, "");
r_config_node_desc (node, "Only print strings matching this extended regex");
r_config_lock (cfg, true);
return true;
}
@@ -49,6 +61,10 @@ static bool r2flutter_core_fini(RCorePluginSession *cps) {
r_config_rm (cfg, R2FLUTTER_CFG_MAPFILE);
r_config_rm (cfg, R2FLUTTER_CFG_NAMEPOOL);
r_config_rm (cfg, R2FLUTTER_CFG_PROFILE);
r_config_rm (cfg, R2FLUTTER_CFG_STR_LIMIT);
r_config_rm (cfg, R2FLUTTER_CFG_STR_MINLEN);
r_config_rm (cfg, R2FLUTTER_CFG_STR_MAXLEN);
r_config_rm (cfg, R2FLUTTER_CFG_STR_FILTER);
r_config_lock (cfg, true);
#endif
return true;
@@ -57,6 +73,10 @@ static bool r2flutter_core_fini(RCorePluginSession *cps) {
static void r2flutter_apply_config(RCore *core, DartCtx *dctx) {
dctx->obf_map_path = r_config_get (core->config, R2FLUTTER_CFG_MAPFILE);
dctx->use_name_pool = r_config_get_b (core->config, R2FLUTTER_CFG_NAMEPOOL);
dctx->str_limit = r_config_get_i (core->config, R2FLUTTER_CFG_STR_LIMIT);
dctx->str_minlen = (int)r_config_get_i (core->config, R2FLUTTER_CFG_STR_MINLEN);
dctx->str_maxlen = (int)r_config_get_i (core->config, R2FLUTTER_CFG_STR_MAXLEN);
dctx->str_filter = r_config_get (core->config, R2FLUTTER_CFG_STR_FILTER);
const char *profile = r_config_get (core->config, R2FLUTTER_CFG_PROFILE);
if (R_STR_ISNOTEMPTY (profile) && !dart_ctx_set_profile_override (dctx, profile)) {
R_LOG_WARN ("Ignoring unsupported Dart snapshot profile override: %s", profile);
@@ -91,7 +111,9 @@ static void r2flutter_subcmd_help(RCore *core, char action) {
static void r2flutter_help(RCore *core) {
r_cons_printf (core->cons,
"Usage: r2flutter [qjr*] <action>\n"
"| r2flutter -A[AA] analyze dart snapshot and apply flags/comments\n"
"| r2flutter -A apply flags, function names and signatures\n"
"| r2flutter -AA also seed anal.gp and apply ObjectPool xrefs\n"
"| r2flutter -AAA also run the full register-tracking scan (slow)\n"
"| r2flutter -c[jr*] dump classes\n"
"| r2flutter -C apply Dart classes, fields, methods and types\n"
"| r2flutter -D prof override Dart snapshot profile by hash or version\n"
@@ -391,13 +413,28 @@ static bool r2flutter_run_cmd(RCore *core, DartCtx *dctx, const R2FlutterCmd *cm
r2flutter_help (core);
return true;
case 'A':
// Tiered analysis:
// -A flags, function names and signatures (fast)
// -AA + anal.gp seeding and the ObjectPool xref graph (data-image
// string references), without the expensive per-function scan
// -AAA + full register-tracking scan (PP-slot comments, field/arg
// tracking, null/bool annotations, indirect-call resolution)
if (cmd->analysis_depth >= 2) {
dctx->dump_fields = 1;
}
// Seed anal.gp/gpseed/roregs with the ObjectPool base for every -A depth
// so plain-r2 analysis can resolve [x27, off] pool loads.
r2flutter_setup_pp_gp (core, dctx);
if (cmd->analysis_depth >= 3) {
r2flutter_analysis_run (core, dctx, dctx->quiet);
} else {
r2flutter_analyze (core, dctx, dctx->quiet);
if (cmd->analysis_depth >= 2) {
int graph_xrefs = r2flutter_apply_pool_xrefs (core, dctx);
if (!dctx->quiet) {
R_LOG_INFO ("r2flutter: applied %d ObjectPool xrefs", graph_xrefs);
}
}
}
return true;
case 'C':
@@ -527,6 +564,7 @@ R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_CORE,
.data = &r_core_plugin_r2flutter,
.version = R2_VERSION,
.abiversion = R2_ABIVERSION
.abiversion = R2_ABIVERSION,
.pkgname = "r2flutter"
};
#endif
+480 -46
View File
@@ -19,8 +19,10 @@ typedef struct {
const DartFieldInfo *field;
const DartStringInfo *string;
const char *type_name;
ut64 pp_off;
ut64 pp_off; // this register is a pool POINTER: PP base + pp_off (from x27 / add)
bool has_pp_off;
ut64 pp_slot; // this register holds the VALUE loaded from PP slot pp_slot (object)
bool has_pp_slot;
} FlutterTrackedValue;
typedef struct {
@@ -41,6 +43,7 @@ typedef struct {
ut64 imm;
bool has_mem;
bool has_imm;
int etype; // effective op type (x86-64 `mov reg,[mem]` reclassified as LOAD/STORE)
} FlutterOpInfo;
typedef struct {
@@ -57,12 +60,31 @@ typedef struct {
typedef struct {
ut64 string_addr;
char *string_value;
bool indirect;
} FlutterPpStringRef;
typedef struct {
HtUP *by_pp_off;
} FlutterPpStringMap;
// Non-string resolution of PP slots (functions, classes, code, ...), so that
// analysis comments can name what a slot holds instead of a bare offset, and
// code/function slots can gain a real xref to their target.
typedef struct {
char *kind;
char *name;
ut64 code_index;
ut64 value_addr;
} FlutterPpRef;
typedef struct {
HtUP *by_pp_off; // pp_off -> FlutterPpRef
HtUP *addr_by_code_index; // code_index -> normalized code address
ut64 pp_base; // ObjectPool base address, so a [PP, off] load can xref pp_base+off
bool is_x64; // x86-64 keeps the heap tag in r15, so a [r15, off] offset is one
// less than the arm64/collector offset; add it back before lookup/xref.
} FlutterPpRefMap;
typedef struct {
HtUP *seen;
RVecFlutterEntry *entries;
@@ -72,15 +94,19 @@ static void flutter_stack_slot_free(void *p) {
free (p);
}
static void flutter_pp_string_ref_free(HtUPKv *kv) {
FlutterPpStringRef *ref = kv->value;
static void flutter_pp_string_ref_free(void *p) {
FlutterPpStringRef *ref = p;
free (ref->string_value);
free (ref);
}
static void flutter_pp_string_bucket_free(HtUPKv *kv) {
r_list_free (kv->value);
}
static void flutter_pp_string_map_init(FlutterPpStringMap *map) {
memset (map, 0, sizeof (*map));
map->by_pp_off = ht_up_new (NULL, flutter_pp_string_ref_free, NULL);
map->by_pp_off = ht_up_new (NULL, flutter_pp_string_bucket_free, NULL);
}
static void flutter_pp_string_map_fini(FlutterPpStringMap *map) {
@@ -133,8 +159,44 @@ static bool flutter_reg_is_stack(const char *name) {
return !strcmp (name, "x15") || !strcmp (name, "sp") || !strcmp (name, "x29") || !strcmp (name, "fp");
}
// Dart's pool pointer (PP): x27 on arm64, r15 on x86-64.
static bool flutter_reg_is_pp(const char *name) {
return !strcmp (name, "x27");
return !strcmp (name, "x27") || !strcmp (name, "r15");
}
// x22 is Dart AOT's NULL_REG: it caches Object::null() for the whole program.
static bool flutter_reg_is_null(const char *name) {
return !strcmp (name, "x22");
}
// The VM lays null, true and false out as adjacent heap objects
// (runtime/vm/pointer_tagging.h): true = null + 4*word_size, false = null +
// 6*word_size. On arm64 AOT the object-alignment word is the 8-byte target word
// regardless of pointer compression, so these are 0x20 / 0x30 on every Dart
// version (verified on cws=8 and cws=4 snapshots).
#define DART_NULL_TRUE_OFFSET 0x20
#define DART_NULL_FALSE_OFFSET 0x30
// Map an x86-64 general-purpose register name (64/32-bit) to a stable slot. Dart
// AOT on x64 uses the same tracker; names never collide with arm64 (x/w vs
// r/rXX), and a single binary is one arch, so sharing the 0..15 slot space is
// safe.
static int flutter_x64_reg_index(const char *name) {
static const char *const names[16] = {
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
};
static const char *const names32[16] = {
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
};
int i;
for (i = 0; i < 16; i++) {
if (!strcmp (name, names[i]) || !strcmp (name, names32[i])) {
return i;
}
}
return -1;
}
static int flutter_reg_index(const char *name) {
@@ -153,6 +215,9 @@ static int flutter_reg_index(const char *name) {
return idx;
}
}
if (name[0] == 'r' || name[0] == 'e') {
return flutter_x64_reg_index (name);
}
return -1;
}
@@ -242,6 +307,22 @@ static bool flutter_parse_shifted_imm(const char *line, ut64 *imm) {
if (!lsl) {
return false;
}
// RArchValue.imm may already include the shift (depending on the ARM
// decoder). Read the unshifted third operand before applying it once.
const char *arg = strchr (line, ',');
arg = arg? strchr (arg + 1, ','): NULL;
if (!arg || arg >= lsl) {
return false;
}
arg++;
while (isspace ((ut8)*arg) || *arg == '#') {
arg++;
}
char *end;
ut64 value = strtoull (arg, &end, 0);
if (end == arg) {
return false;
}
const char *p = lsl + 3;
while (isspace ((ut8)*p)) {
p++;
@@ -252,11 +333,11 @@ static bool flutter_parse_shifted_imm(const char *line, ut64 *imm) {
if (!isdigit ((ut8)*p)) {
return false;
}
int shift = atoi (p);
if (shift <= 0 || shift >= 63) {
ut64 shift = strtoull (p, NULL, 0);
if (shift >= 64) {
return false;
}
*imm <<= shift;
*imm = value << shift;
return true;
}
@@ -304,7 +385,8 @@ static void flutter_parse_mem_operand(const char *line, FlutterOpInfo *info) {
while (isspace ((ut8)*p)) {
p++;
}
if (*p != ',') {
// arm64 writes `[x27, 0x610]`, x86-64 writes `[r15 + 0x610]`.
if (*p != ',' && *p != '+') {
return;
}
p++;
@@ -345,7 +427,18 @@ static bool flutter_parse_opinfo(const RAnalOp *op, FlutterOpInfo *info) {
return false;
}
memset (info, 0, sizeof (*info));
const int type = op->type & R_ANAL_OP_TYPE_MASK;
int type = op->type & R_ANAL_OP_TYPE_MASK;
// x86-64 types a memory load/store as MOV; reclassify `mov reg, [mem]` as a
// LOAD and `mov [mem], reg` as a STORE by where the brackets sit relative to
// the operand separator, so the arm64-shaped load/store logic applies.
if (type == R_ANAL_OP_TYPE_MOV && R_STR_ISNOTEMPTY (op->mnemonic)) {
const char *br = strchr (op->mnemonic, '[');
const char *comma = strchr (op->mnemonic, ',');
if (br && comma) {
type = br > comma? R_ANAL_OP_TYPE_LOAD: R_ANAL_OP_TYPE_STORE;
}
}
info->etype = type;
const RArchValue *value = RVecRArchValue_at (&op->dsts, 0);
if (type != R_ANAL_OP_TYPE_STORE) {
flutter_opinfo_add_value (info, value, true);
@@ -368,7 +461,7 @@ static bool flutter_parse_opinfo(const RAnalOp *op, FlutterOpInfo *info) {
if (info->n_regs == 0 && (type == R_ANAL_OP_TYPE_RCALL || type == R_ANAL_OP_TYPE_UCALL || type == R_ANAL_OP_TYPE_ICALL || type == R_ANAL_OP_TYPE_IRCALL)) {
flutter_parse_first_operand_reg (op->mnemonic, info);
}
if (info->has_imm && R_STR_ISNOTEMPTY (op->mnemonic)) {
if (type == R_ANAL_OP_TYPE_ADD && info->has_imm && R_STR_ISNOTEMPTY (op->mnemonic)) {
(void)flutter_parse_shifted_imm (op->mnemonic, &info->imm);
}
return info->n_regs > 0 || info->has_mem || info->has_imm;
@@ -430,13 +523,44 @@ static void flutter_add_ref(RCore *core, ut64 from, ut64 to, RAnalRefType type)
r_anal_xrefs_set (core->anal, from, to, type);
}
// Annotate the Dart NULL_REG (x22) idioms so booleans and null checks read
// clearly: `add d, x22, #0x20/#0x30` materialises true/false, `mov d, x22`
// loads null, and a compare against x22 is a null check.
static void flutter_annotate_null_reg(RCore *core, ut64 at, int optype, const FlutterOpInfo *info, FlutterAnalStats *stats) {
if (!core || !info) {
return;
}
if (optype == R_ANAL_OP_TYPE_ADD && info->n_regs >= 2 && info->has_imm && flutter_reg_is_null (info->regs[1])) {
const char *b = info->imm == DART_NULL_TRUE_OFFSET? "true": info->imm == DART_NULL_FALSE_OFFSET? "false": NULL;
if (b) {
char *msg = r_str_newf ("dart: %s", b);
flutter_append_comment (core, at, msg, stats);
free (msg);
}
return;
}
if (optype == R_ANAL_OP_TYPE_MOV && info->n_regs >= 2 && flutter_reg_is_null (info->regs[1])) {
flutter_append_comment (core, at, "dart: null", stats);
return;
}
if (optype == R_ANAL_OP_TYPE_CMP) {
int i;
for (i = 0; i < info->n_regs; i++) {
if (flutter_reg_is_null (info->regs[i])) {
flutter_append_comment (core, at, "dart: compare with null", stats);
return;
}
}
}
}
static bool flutter_model_load(FlutterAnalModel *model, RCore *core, DartCtx *dctx) {
if (!model || !core || !dctx) {
return false;
}
DartCtx ctx = *dctx;
ctx.core = core;
dart_recovery_model_load (&ctx, model, DART_RECOVERY_STRINGS | DART_RECOVERY_CLASSES | DART_RECOVERY_CLASS_FIELDS | DART_RECOVERY_METHOD_INDEX);
dart_recovery_model_load (&ctx, model, DART_RECOVERY_STRINGS | DART_RECOVERY_CLASSES | DART_RECOVERY_CLASS_FIELDS | DART_RECOVERY_METHOD_INDEX | DART_RECOVERY_IT);
if (!model->strings || !model->classes) {
flutter_model_fini (model);
return false;
@@ -448,13 +572,23 @@ static void flutter_pp_string_map_add(FlutterPpStringMap *map, const ModernPoolS
if (!map || !map->by_pp_off || !info || R_STR_ISEMPTY (info->string_value) || !info->string_addr) {
return;
}
if (ht_up_find (map->by_pp_off, info->pp_offset, NULL)) {
return;
RList *refs = ht_up_find (map->by_pp_off, info->pp_offset, NULL);
if (!refs) {
refs = r_list_newf (flutter_pp_string_ref_free);
ht_up_insert (map->by_pp_off, info->pp_offset, refs);
}
RListIter *it;
FlutterPpStringRef *existing;
r_list_foreach (refs, it, existing) {
if (existing->string_addr == info->string_addr) {
return;
}
}
FlutterPpStringRef *ref = R_NEW0 (FlutterPpStringRef);
ref->string_addr = info->string_addr;
ref->string_value = strdup (info->string_value);
ht_up_insert (map->by_pp_off, info->pp_offset, ref);
ref->indirect = strcmp (info->target_kind, "object_pool.entry") != 0;
r_list_append (refs, ref);
}
static void flutter_pp_string_ref_cb(const ModernPoolStrRef *info, void *user) {
@@ -476,27 +610,141 @@ static bool flutter_collect_pp_strings_from_snapshot(DartCtx *ctx, ut64 snapshot
.num_clusters = sh.nc,
.num_base_objects = sh.nb,
};
return modern_collect_direct_pool_strrefs (&req, wanted, flutter_pp_string_ref_cb, map);
return modern_collect_pool_value_strrefs (&req, wanted, flutter_pp_string_ref_cb, map);
}
static void flutter_pp_string_map_load(DartCtx *ctx, HtUP *wanted, FlutterPpStringMap *map) {
if (!ctx || !map || find_snapshots (ctx) != 0) {
return;
}
// When we init the layout here it may live in layout_tmp (a stack buffer)
// with dart_ctx_init_layout returning NULL. We must still clear ctx->layout
// on the way out, or a later consumer would dereference a dangling pointer.
DartVerLayout layout_tmp;
DartVerLayout *layout_owned = ctx->layout? NULL: dart_ctx_init_layout (ctx, &layout_tmp);
bool layout_ours = !ctx->layout;
DartVerLayout *layout_owned = layout_ours? dart_ctx_init_layout (ctx, &layout_tmp): NULL;
if (!flutter_collect_pp_strings_from_snapshot (ctx, ctx->iso_data, wanted, map)) {
flutter_collect_pp_strings_from_snapshot (ctx, ctx->vm_data, wanted, map);
}
if (layout_owned) {
if (layout_ours) {
dart_ctx_fini_layout (ctx, layout_owned);
}
}
static const FlutterPpStringRef *flutter_pp_string_map_get(FlutterPpStringMap *map, ut64 pp_off) {
static RList *flutter_pp_string_map_get(FlutterPpStringMap *map, ut64 pp_off) {
return map && map->by_pp_off? ht_up_find (map->by_pp_off, pp_off, NULL): NULL;
}
static void flutter_pp_ref_free(HtUPKv *kv) {
FlutterPpRef *ref = kv->value;
free (ref->kind);
free (ref->name);
free (ref);
}
static void flutter_pp_ref_map_init(FlutterPpRefMap *map) {
memset (map, 0, sizeof (*map));
map->by_pp_off = ht_up_new (NULL, flutter_pp_ref_free, NULL);
map->addr_by_code_index = ht_up_new0 ();
}
static void flutter_pp_ref_map_fini(FlutterPpRefMap *map) {
if (!map) {
return;
}
ht_up_free (map->by_pp_off);
ht_up_free (map->addr_by_code_index);
memset (map, 0, sizeof (*map));
}
static void flutter_pp_ref_cb(const ModernPoolRefInfo *info, void *user) {
FlutterPpRefMap *map = user;
if (!map || !map->by_pp_off || !info || R_STR_ISEMPTY (info->kind)) {
return;
}
// Strings are handled by the dedicated string map; skip them here so the
// two maps stay cheap and the string path keeps priority.
if (!strcmp (info->kind, "string") || ht_up_find (map->by_pp_off, info->pp_offset, NULL)) {
return;
}
FlutterPpRef *ref = R_NEW0 (FlutterPpRef);
ref->kind = strdup (info->kind);
ref->name = R_STR_ISNOTEMPTY (info->name)? strdup (info->name): NULL;
ref->code_index = info->code_index;
ref->value_addr = info->value_addr;
ht_up_insert (map->by_pp_off, info->pp_offset, ref);
}
static void flutter_pp_ref_map_load(DartCtx *ctx, FlutterPpRefMap *map) {
if (!ctx || !map || find_snapshots (ctx) != 0) {
return;
}
// See flutter_pp_string_map_load: clear ctx->layout on exit when we init it,
// since it may point at the stack buffer layout_tmp.
DartVerLayout layout_tmp;
bool layout_ours = !ctx->layout;
DartVerLayout *layout_owned = layout_ours? dart_ctx_init_layout (ctx, &layout_tmp): NULL;
// The ObjectPool lives in the isolate snapshot; fall back to the VM snapshot
// like flutter_pp_string_map_load does.
const ut64 bases[2] = { ctx->iso_data, ctx->vm_data };
for (int i = 0; i < 2; i++) {
ut64 snapshot_base = bases[i];
DartSnapshotHeader sh = { 0 };
if (!snapshot_base || !dart_snapshot_header_read (ctx, snapshot_base, &sh) || !sh.ok) {
continue;
}
const ModernReq req = {
.ctx = ctx,
.cluster_start = sh.cluster_start,
.cluster_end = snapshot_base + sh.total_len,
.num_clusters = sh.nc,
.num_base_objects = sh.nb,
};
if (modern_collect_direct_pool_refs (&req, flutter_pp_ref_cb, map)) {
break;
}
}
// Map code_index -> entrypoint address via the instruction table, so a
// code/function slot can be xref'd to its real target.
RVecDartInstructionTableEntry *entries = dart_pool_extract_instruction_table (ctx);
if (entries) {
DartInstructionTableEntry *entry;
R_VEC_FOREACH (entries, entry) {
if (!entry->has_code || !entry->address) {
continue;
}
// Strip the low Thumb/tag bit, matching dart_app's code-addr normalization.
ut64 addr = (entry->address & 1ULL)? entry->address - 1: entry->address;
ht_up_update (map->addr_by_code_index, entry->code_index, (void *)addr);
}
dart_instruction_table_list_free (entries);
}
// The ObjectPool base, so a [PP, off] load can xref the pool slot at
// pp_base + off. r2flutter_setup_pp_gp already resolved it into anal.gp.
if (ctx->core) {
map->pp_base = (ut64)r_config_get_i (ctx->core->config, "anal.gp");
const char *arch = r_config_get (ctx->core->config, "asm.arch");
const int bits = (int)r_config_get_i (ctx->core->config, "asm.bits");
map->is_x64 = arch && bits == 64 && (!strcmp (arch, "x86") || !strcmp (arch, "x64"));
}
if (layout_ours) {
dart_ctx_fini_layout (ctx, layout_owned);
}
}
static const FlutterPpRef *flutter_pp_ref_map_get(FlutterPpRefMap *map, ut64 pp_off) {
return map && map->by_pp_off? ht_up_find (map->by_pp_off, pp_off, NULL): NULL;
}
static ut64 flutter_pp_ref_code_addr(FlutterPpRefMap *map, ut64 code_index) {
if (!map || !map->addr_by_code_index || code_index == UT64_MAX) {
return 0;
}
bool found = false;
ut64 addr = (ut64)ht_up_find (map->addr_by_code_index, code_index, &found);
return found? addr: 0;
}
static void flutter_apply_model_to_core(FlutterAnalModel *model, RCore *core, FlutterAnalStats *stats) {
if (!model || !core) {
return;
@@ -656,6 +904,17 @@ static RVecFlutterEntry *flutter_collect_entries(RCore *core, const DartApp *app
flutter_collect_entries_from_flags (seen, entries, core);
flutter_collect_entries_from_app (seen, entries, app);
flutter_collect_entries_from_model (seen, entries, model);
// Entries before first_entry_with_code still contain executable Dart code;
// only their Code objects were discarded by the precompiler.
if (model->it_entries) {
DartInstructionTableEntry *entry;
R_VEC_FOREACH (model->it_entries, entry) {
if (entry->address && !ht_up_find (seen, entry->address, NULL)) {
RVecFlutterEntry_push_back (entries, &entry->address);
ht_up_insert (seen, entry->address, entries);
}
}
}
ht_up_free (seen);
return entries;
}
@@ -677,6 +936,18 @@ static void flutter_ensure_functions(RCore *core, RVecFlutterEntry *entries) {
if (restore_log_level) {
r_log_set_level (R_LOG_LEVEL_INFO);
}
const bool prev_trycatch = dart_core_trycatch_suspend (core);
// `af` only needs to recover each function's basic blocks here; the Dart
// scan tracks its own args/fields and resolves calls from the snapshot, so
// r2's variable analysis, call-following and jump-table recovery are pure
// overhead - disabling them roughly halves this af storm, the dominant cost
// of -AAA, without changing the recovered blocks.
bool prev_calls = r_config_get_b (core->config, "anal.calls");
bool prev_vars = r_config_get_b (core->config, "anal.vars");
bool prev_jmptbl = r_config_get_b (core->config, "anal.jmp.tbl");
r_config_set_b (core->config, "anal.calls", false);
r_config_set_b (core->config, "anal.vars", false);
r_config_set_b (core->config, "anal.jmp.tbl", false);
ut64 *addrp;
R_VEC_FOREACH (entries, addrp) {
if (!*addrp) {
@@ -686,6 +957,10 @@ static void flutter_ensure_functions(RCore *core, RVecFlutterEntry *entries) {
r_core_cmdf (core, "af @ 0x%" PFMT64x, *addrp);
}
}
r_config_set_b (core->config, "anal.calls", prev_calls);
r_config_set_b (core->config, "anal.vars", prev_vars);
r_config_set_b (core->config, "anal.jmp.tbl", prev_jmptbl);
dart_core_trycatch_restore (core, prev_trycatch);
if (restore_log_level) {
r_log_set_level (old_level);
}
@@ -886,7 +1161,41 @@ static bool flutter_process_stack_store(FlutterAnalState *state, const FlutterOp
return true;
}
static bool flutter_process_pp_load(RCore *core, FlutterAnalState *state, FlutterPpStringMap *pp_strings, ut64 at, const FlutterOpInfo *info, FlutterAnalStats *stats) {
// Annotate a non-string PP slot: name what the slot holds and, when it points
// at a code/data object we can locate, add a navigable xref to the target.
// Returns true when the slot resolved to a known entry.
static bool flutter_annotate_pp_ref(RCore *core, FlutterPpRefMap *pp_refs, ut64 at, ut64 pp_off, bool is_call, FlutterAnalStats *stats) {
const FlutterPpRef *ref = flutter_pp_ref_map_get (pp_refs, pp_off);
if (!ref) {
return false;
}
ut64 target = flutter_pp_ref_code_addr (pp_refs, ref->code_index);
const char *label = NULL;
if (target) {
RFlagItem *fi = r_flag_get_at (core->flags, target, false);
label = (fi && R_STR_ISNOTEMPTY (fi->name))? fi->name: ref->name;
flutter_add_ref (core, at, target, is_call? R_ANAL_REF_TYPE_CALL: (R_ANAL_REF_TYPE_DATA | R_ANAL_REF_TYPE_READ));
} else if (ref->value_addr) {
label = ref->name;
flutter_add_ref (core, at, ref->value_addr, R_ANAL_REF_TYPE_DATA | R_ANAL_REF_TYPE_READ);
} else {
label = ref->name;
}
const char *what = is_call? "indirect call via PP+0x": "PP slot +0x";
char *msg;
if (R_STR_ISNOTEMPTY (label)) {
char *escaped = r_str_escape_utf8 (label, false, true);
msg = r_str_newf ("dart: %s%" PFMT64x " %s %s", what, pp_off, ref->kind, escaped);
free (escaped);
} else {
msg = r_str_newf ("dart: %s%" PFMT64x " %s", what, pp_off, ref->kind);
}
flutter_append_comment (core, at, msg, stats);
free (msg);
return true;
}
static bool flutter_process_pp_load(RCore *core, FlutterAnalState *state, FlutterPpStringMap *pp_strings, FlutterPpRefMap *pp_refs, ut64 at, const FlutterOpInfo *info, FlutterAnalStats *stats) {
if (!state || !info || info->n_regs < 1 || !info->has_mem) {
return false;
}
@@ -904,25 +1213,43 @@ static bool flutter_process_pp_load(RCore *core, FlutterAnalState *state, Flutte
}
pp_off = state->regs[base].pp_off + (ut64)info->mem_disp;
}
// On x86-64 the heap tag is carried in r15, so the instruction offset is one
// less than the collector/arm64 slot offset. Add it back to get the
// canonical offset used for resolution maps and the slot address.
const ut64 slot_off = pp_off + (pp_refs && pp_refs->is_x64? 1: 0);
// The destination now holds the pool OBJECT at pp_off, not a PP pointer.
// Marking it has_pp_off would make a later [dst, field] load look like a
// bogus pool slot (e.g. a Code entry-point deref read as PP+off+7).
memset (&state->regs[dst], 0, sizeof (state->regs[dst]));
state->regs[dst].has_pp_off = true;
state->regs[dst].pp_off = pp_off;
const FlutterPpStringRef *string_ref = flutter_pp_string_map_get (pp_strings, pp_off);
if (string_ref) {
state->regs[dst].has_pp_slot = true;
state->regs[dst].pp_slot = slot_off;
// Link the instruction to the ObjectPool slot it reads (pp_base + off), so
// `axt` on the slot shows the loading code; the slot's own ref to its value
// (applied by -AA) then chains through to the string/object. Works on any
// arch since pp_base + off is the slot address regardless of index scheme.
if (pp_refs && pp_refs->pp_base) {
flutter_add_ref (core, at, pp_refs->pp_base + slot_off, R_ANAL_REF_TYPE_DATA | R_ANAL_REF_TYPE_READ);
}
RList *strings = flutter_pp_string_map_get (pp_strings, slot_off);
FlutterPpStringRef *first = strings? r_list_first (strings): NULL;
if (!first || first->indirect) {
if (!flutter_annotate_pp_ref (core, pp_refs, at, slot_off, false, stats)) {
char *msg = r_str_newf ("dart: PP slot +0x%" PFMT64x, slot_off);
flutter_append_comment (core, at, msg, stats);
free (msg);
}
}
RListIter *it;
FlutterPpStringRef *string_ref;
r_list_foreach (strings, it, string_ref) {
flutter_set_flag (core, "dart.str", string_ref->string_value, string_ref->string_addr, (ut32)strlen (string_ref->string_value), true);
flutter_add_ref (core, at, string_ref->string_addr, R_ANAL_REF_TYPE_STRN | R_ANAL_REF_TYPE_READ);
stats->string_refs++;
char *escaped = r_str_escape_utf8 (string_ref->string_value, false, true);
char *msg = r_str_newf ("dart: PP slot +0x%" PFMT64x " string \"%s\"", pp_off, escaped);
char *msg = r_str_newf ("dart: PP slot +0x%" PFMT64x " %sstring \"%s\"", pp_off, string_ref->indirect? "contains ": "", escaped);
flutter_append_comment (core, at, msg, stats);
free (msg);
free (escaped);
} else {
char *msg = r_str_newf ("dart: "
"PP slot +0x%" PFMT64x,
pp_off);
flutter_append_comment (core, at, msg, stats);
free (msg);
}
stats->pp_refs++;
return true;
@@ -979,7 +1306,29 @@ static bool flutter_process_field_store(RCore *core, FlutterAnalModel *model, Fl
return true;
}
static void flutter_process_indirect_call(RCore *core, FlutterAnalState *state, ut64 at, const FlutterOpInfo *info, FlutterAnalStats *stats) {
// Keep the pool-slot taint across a dereference of a pool object, such as the
// `ldr xN, [xN, #entry_point]` that extracts a Code object's entry point right
// before an indirect call. Without this the slot association is lost.
static bool flutter_process_pp_slot_deref(FlutterAnalState *state, const FlutterOpInfo *info) {
if (!state || !info || info->n_regs < 1 || !info->has_mem) {
return false;
}
int base = flutter_reg_index (info->mem_base);
if (base < 0 || !state->regs[base].has_pp_slot) {
return false;
}
int dst = flutter_reg_index (info->regs[0]);
if (dst < 0) {
return false;
}
ut64 slot = state->regs[base].pp_slot;
memset (&state->regs[dst], 0, sizeof (state->regs[dst]));
state->regs[dst].has_pp_slot = true;
state->regs[dst].pp_slot = slot;
return true;
}
static void flutter_process_indirect_call(RCore *core, FlutterAnalState *state, FlutterPpRefMap *pp_refs, ut64 at, const FlutterOpInfo *info, FlutterAnalStats *stats) {
if (!core || !state || !info || info->n_regs < 1) {
return;
}
@@ -987,15 +1336,23 @@ static void flutter_process_indirect_call(RCore *core, FlutterAnalState *state,
if (reg < 0) {
return;
}
if (state->regs[reg].has_pp_off) {
char *msg = r_str_newf ("dart: indirect call via PP+0x%" PFMT64x, state->regs[reg].pp_off);
flutter_append_comment (core, at, msg, stats);
free (msg);
// The call target is the object held in the register (a Code/Function
// loaded from a PP slot), possibly after an entry-point deref. Use the slot
// that value came from, not a PP-pointer offset.
if (state->regs[reg].has_pp_slot) {
ut64 slot = state->regs[reg].pp_slot;
// A call through a resolved code slot gets a real CALL xref and the
// target name; otherwise keep the plain via-PP note.
if (!flutter_annotate_pp_ref (core, pp_refs, at, slot, true, stats)) {
char *msg = r_str_newf ("dart: indirect call via PP+0x%" PFMT64x, slot);
flutter_append_comment (core, at, msg, stats);
free (msg);
}
stats->pp_refs++;
}
}
static void flutter_scan_function(RCore *core, FlutterAnalModel *model, FlutterPpStringMap *pp_strings, RAnalFunction *fcn, FlutterAnalStats *stats) {
static void flutter_scan_function(RCore *core, FlutterAnalModel *model, FlutterPpStringMap *pp_strings, FlutterPpRefMap *pp_refs, RAnalFunction *fcn, FlutterAnalStats *stats) {
if (!core || !model || !fcn || !stats) {
return;
}
@@ -1013,9 +1370,15 @@ static void flutter_scan_function(RCore *core, FlutterAnalModel *model, FlutterP
}
HtUP *seen_ops = ht_up_new0 ();
RListIter *it;
RAnalBlock *bb;
#if R2_ABIVERSION >= 168
RAnalBlock **it;
R_VEC_FOREACH (&fcn->bbs, it) {
bb = *it;
#else
RListIter *it;
r_list_foreach (fcn->bbs, it, bb) {
#endif
if (!bb || bb->size == 0) {
continue;
}
@@ -1042,8 +1405,13 @@ static void flutter_scan_function(RCore *core, FlutterAnalModel *model, FlutterP
if (has_info && info.has_imm) {
flutter_process_direct_ref (core, model, at, info.imm, stats);
}
if (has_info) {
flutter_annotate_null_reg (core, at, op->type & R_ANAL_OP_TYPE_MASK, &info, stats);
}
switch (op->type & R_ANAL_OP_TYPE_MASK) {
// Use the effective type so x86-64 memory MOVs dispatch as LOAD/STORE.
int etype = has_info? info.etype: (int)(op->type & R_ANAL_OP_TYPE_MASK);
switch (etype) {
case R_ANAL_OP_TYPE_MOV:
if (!flutter_process_mov (&state, &info) && has_info && info.n_regs > 0) {
int dst = flutter_reg_index (info.regs[0]);
@@ -1056,9 +1424,10 @@ static void flutter_scan_function(RCore *core, FlutterAnalModel *model, FlutterP
(void)flutter_process_add (&state, &info);
break;
case R_ANAL_OP_TYPE_LOAD:
if (!flutter_process_pp_load (core, &state, pp_strings, at, &info, stats) &&
if (!flutter_process_pp_load (core, &state, pp_strings, pp_refs, at, &info, stats) &&
!flutter_process_stack_load (&state, &info) &&
!flutter_process_field_load (core, model, &state, at, &info, stats) &&
!flutter_process_pp_slot_deref (&state, &info) &&
has_info && info.n_regs > 0) {
int dst = flutter_reg_index (info.regs[0]);
if (dst >= 0) {
@@ -1081,7 +1450,7 @@ static void flutter_scan_function(RCore *core, FlutterAnalModel *model, FlutterP
case R_ANAL_OP_TYPE_ICALL:
case R_ANAL_OP_TYPE_IRCALL:
if (has_info) {
flutter_process_indirect_call (core, &state, at, &info, stats);
flutter_process_indirect_call (core, &state, pp_refs, at, &info, stats);
}
flutter_state_clobber_callers (&state);
break;
@@ -1096,7 +1465,7 @@ static void flutter_scan_function(RCore *core, FlutterAnalModel *model, FlutterP
flutter_state_fini (&state);
}
static void flutter_scan_functions(RCore *core, FlutterAnalModel *model, FlutterPpStringMap *pp_strings, RVecFlutterEntry *entries, FlutterAnalStats *stats) {
static void flutter_scan_functions(RCore *core, FlutterAnalModel *model, FlutterPpStringMap *pp_strings, FlutterPpRefMap *pp_refs, RVecFlutterEntry *entries, FlutterAnalStats *stats) {
if (!core || !model || !entries || !stats) {
return;
}
@@ -1111,11 +1480,67 @@ static void flutter_scan_functions(RCore *core, FlutterAnalModel *model, Flutter
continue;
}
ht_up_insert (seen_fcns, fcn->addr, fcn);
flutter_scan_function (core, model, pp_strings, fcn, stats);
flutter_scan_function (core, model, pp_strings, pp_refs, fcn, stats);
}
ht_up_free (seen_fcns);
}
// Expose the reconstructed ObjectPool as r2's global pointer so that plain-r2
// analysis and ESIL resolve `[x27, off]` loads to pool addresses, matching how
// `r2flutter -p -r` already wires it up. x27 (PP) is the only Dart reserved
// register with a static address; x22 (NULL_REG) and x26 (THR) are runtime
// pointers and cannot be seeded this way.
void r2flutter_setup_pp_gp(RCore *core, DartCtx *dctx) {
if (!core || !dctx) {
return;
}
// Resolve on a shallow copy: dart_resolve_pp_info populates the read cache
// (ctx->rmem) and can leave a stale layout pointer in the context. The real
// dctx is copied by value into the analysis DartApp, so polluting it here
// would double-free that cache. The copy shares heap-owned pointers with
// dctx, so we only release what we allocated into it (its own rmem).
DartCtx probe = *dctx;
probe.rmem = NULL;
probe.layout = NULL;
// Dart's PP register is x27 on arm64 and r15 on x86-64.
const char *arch = r_config_get (core->config, "asm.arch");
const int bits = (int)r_config_get_i (core->config, "asm.bits");
const bool is_x64 = arch && bits == 64 && (!strcmp (arch, "x86") || !strcmp (arch, "x64"));
const char *pp_reg = is_x64? "r15": "x27";
DartPpInfo pp = { 0 };
if (dart_resolve_pp_info (&probe, &pp) && pp.base) {
char roregs[32];
snprintf (roregs, sizeof (roregs), "%s,gp,zero", pp_reg);
r_config_set_i (core->config, "anal.gp", pp.base);
r_config_set (core->config, "anal.gpseed", pp_reg);
r_config_set (core->config, "anal.roregs", roregs);
r_flag_set (core->flags, "PP", pp.base, 1);
}
dart_pp_info_fini (&pp);
dart_read_cache_free (probe.rmem);
}
// Apply the recovered ObjectPool xref graph (including data-image references
// such as a const object pointing at a string) so `axt` resolves pool strings
// that no instruction loads directly. Runs on a clean copy of the context:
// extraction needs the pristine state the standalone `-x` command sees, and the
// copy shares heap-owned pointers so only its own read cache is freed. Cheap
// relative to the function scan, which is why -AA can afford it. Returns the
// number of xrefs applied.
int r2flutter_apply_pool_xrefs(RCore *core, DartCtx *dctx) {
if (!core || !dctx) {
return 0;
}
DartCtx xrctx = *dctx;
xrctx.core = core;
xrctx.rmem = NULL;
xrctx.layout = NULL;
xrctx.dump_string_refs = true;
int applied = dart_pool_apply_xrefs (&xrctx);
dart_read_cache_free (xrctx.rmem);
return applied;
}
bool r2flutter_analysis_run(RCore *core, DartCtx *dctx, bool quiet) {
R_RETURN_VAL_IF_FAIL (core && dctx, false);
DartApp *app = dart_app_new_from_core (core, dctx);
@@ -1141,23 +1566,32 @@ bool r2flutter_analysis_run(RCore *core, DartCtx *dctx, bool quiet) {
flutter_pp_string_map_init (&pp_strings);
flutter_pp_string_map_load (&app->dctx, NULL, &pp_strings);
FlutterPpRefMap pp_refs;
flutter_pp_ref_map_init (&pp_refs);
flutter_pp_ref_map_load (&app->dctx, &pp_refs);
RVecFlutterEntry *entries = flutter_collect_entries (core, app, &model);
flutter_ensure_functions (core, entries);
flutter_scan_functions (core, &model, &pp_strings, entries, &stats);
dart_dumper_name_functions (app);
flutter_scan_functions (core, &model, &pp_strings, &pp_refs, entries, &stats);
int graph_xrefs = r2flutter_apply_pool_xrefs (core, dctx);
if (!quiet) {
R_LOG_INFO ("Flutter analysis: %d functions, %d calls, %d fields, %d classes, %d types, %d strings, %d PP refs",
R_LOG_INFO ("Flutter analysis: %d functions, %d calls, %d fields, %d classes, %d types, %d strings, %d PP refs, %d graph xrefs",
(int)stats.functions,
(int)stats.call_xrefs,
(int)stats.field_refs,
(int)stats.class_refs,
(int)stats.type_refs,
(int)stats.string_refs,
(int)stats.pp_refs);
(int)stats.pp_refs,
graph_xrefs);
}
RVecFlutterEntry_free (entries);
flutter_pp_string_map_fini (&pp_strings);
flutter_pp_ref_map_fini (&pp_refs);
flutter_model_fini (&model);
dart_app_free (app);
return true;
+2
View File
@@ -5,5 +5,7 @@
#include "../../include/r2flutter/dart_r2.h"
bool r2flutter_analysis_run(RCore *core, DartCtx *dctx, bool quiet);
void r2flutter_setup_pp_gp(RCore *core, DartCtx *dctx);
int r2flutter_apply_pool_xrefs(RCore *core, DartCtx *dctx);
#endif
+1
View File
@@ -169,6 +169,7 @@ int main(int argc, char **argv) {
break;
case 'l':
dctx.dump_fns_limit = atoi (opt.arg);
dctx.str_limit = r_num_get (NULL, opt.arg);
break;
case 'n':
dctx.use_name_pool = true;
+1 -1
View File
@@ -6,7 +6,7 @@
"expect": {
"contains": [
"class _Closure@0150898 (size=64)",
"+0x428 dynamic _context@0150898",
"+0x28 dynamic _context@0150898",
"class _Uri@0150898 (size=96)",
"+0x0 dynamic _portMap@1026248 static final"
],
+14
View File
@@ -0,0 +1,14 @@
{
"name": "pool-ios-authpass-shift1",
"cwd": "test",
"cmd": ["../bin/r2flutter", "-p", "bins/ios/AuthPass.app/Frameworks/App.framework/App"],
"timeout": 30,
"expect": {
"contains": [
"length: 43268 entries"
],
"not_contains": [
"PP not resolved"
]
}
}
+4 -4
View File
@@ -8,8 +8,8 @@ EOF
EXPECT=<<EOF
class Pointer (size=32)
methods:
0x00000000 get:hashCode (GetterFunction)
0x00000000 == (RegularFunction)
0x00115f2c get:hashCode (GetterFunction)
0x001299fc == (RegularFunction)
class NativeType (size=16)
class NativeFunction (size=16)
EOF
@@ -27,8 +27,8 @@ EXPECT=<<EOF
# class Pointer (size=32)
# type_params: 1
"td struct dart_Pointer { };"
# method 0x00000000 get:hashCode (GetterFunction)
# method 0x00000000 == (RegularFunction)
# method 0x00115f2c get:hashCode (GetterFunction)
# method 0x001299fc == (RegularFunction)
# class NativeType (size=16)
EOF
RUN
+4 -4
View File
@@ -8,8 +8,8 @@ EOF
EXPECT=<<EOF
class Pointer (size=32)
methods:
0x00000000 get:hashCode (GetterFunction)
0x00000000 == (RegularFunction)
0x00c6ab64 get:hashCode (GetterFunction)
0x00d8bde8 == (RegularFunction)
class NativeType (size=16)
class NativeFunction (size=16)
EOF
@@ -43,8 +43,8 @@ EXPECT=<<EOF
# class Pointer (size=32)
# type_params: 1
"td struct dart_Pointer { };"
# method 0x00000000 get:hashCode (GetterFunction)
# method 0x00000000 == (RegularFunction)
# method 0x00c6ab64 get:hashCode (GetterFunction)
# method 0x00d8bde8 == (RegularFunction)
# class NativeType (size=16)
EOF
RUN
+9 -9
View File
@@ -33,14 +33,14 @@ ic dart_Future
EOF
EXPECT=<<EOF
class dart_Future
0x00000000 method dart_Future sC Future_error
0x00000000 method dart_Future sC Future_
0x00000000 method dart_Future s _anonymous_closure_
0x00000000 method dart_Future sC Future_value
0x00000000 method dart_Future s wait
0x00000000 method dart_Future s handleError
0x00000000 method dart_Future sC Future_delayed
0x00000000 method dart_Future sC Future_microtask
0x00000000 method dart_Future sC Future_sync
0x005d4f54 method dart_Future sC Future_error
0x005d70cc method dart_Future sC Future_
0x005d71b8 method dart_Future s _anonymous_closure_
0x005e4a98 method dart_Future sC Future_value
0x0060d7d4 method dart_Future s wait
0x0060dfac method dart_Future s handleError
0x0062edcc method dart_Future sC Future_delayed
0x006d5018 method dart_Future sC Future_microtask
0x00943c08 method dart_Future sC Future_sync
EOF
RUN
+30
View File
@@ -0,0 +1,30 @@
NAME=dart-313-early-base-object-clusters
FILE=malloc://0x8d
CMDS=<<EOF
L ../src/r2/core_flutter.dylib
L ../src/r2/core_flutter.so
wx 50414421f5f5dcdc85000000000000000200000000000000303435313930376332656161383436376538343863303036376266653865643470726f647563742061726d3634206e6f2d636f6d707265737365642d706f696e746572730082858585890060c581800060c681820020ca810000cb810060c5818180828181c1bfbfbfc0c2c5c6c7c3818101810181
r2flutter -q -j -HHH -l 8~{snapshots[0].clusters_parsed}
r2flutter -q -j -HHH -l 8~{snapshots[0].clusters[0].fill_status}
r2flutter -q -j -HHH -l 8~{snapshots[0].clusters[1].alloc}
r2flutter -q -j -HHH -l 8~{snapshots[0].clusters[1].fill}
r2flutter -q -j -HHH -l 8~{snapshots[0].clusters[1].fill_status}
r2flutter -q -j -HHH -l 8~{snapshots[0].clusters[2].fill_status}
r2flutter -q -j -HHH -l 8~{snapshots[0].clusters[3].fill_status}
r2flutter -q -j -HHH -l 8~{snapshots[0].clusters[4].fill_status}
r2flutter -q -j -p~{cluster_index}
r2flutter -q -j -O PP+0x10~{pp_slot.cluster_index}
EOF
EXPECT=<<EOF
true
ok
variable
local_var_descriptors
ok
ok
ok
ok
4
4
EOF
RUN
+1 -1
View File
@@ -117,7 +117,7 @@ dart
0x00000020 dart field 2 genericItems
0x00000028 dart field 3 callback
0x00000000 [0x00000000 - 0x00000000] 0 dart class 1 dart_TestInterface
pf [16].qppp fieldA items genericItems callback
'pf [16].qppp fieldA items genericItems callback
EOF
RUN
+25
View File
@@ -0,0 +1,25 @@
NAME=pp-code-resolve-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -j -O pp+0x40~{pp_slot.resolved_kind}
r2flutter -q -j -O pp+0x40~{pp_slot.resolved_code_index}
r2flutter -q -j -O pp+0x48~{pp_slot.resolved_code_index}
r2flutter -q -j -HHH -l 500~{snapshots[1].clusters[365].object_pools[0].entries[6].resolved_code_index}
r2flutter -q -AAA
CC. @ 0x3f28cc
axfj @ 0x3f28cc~{[0].to}
axfj @ 0x3f28cc~{[0].type}
EOF
EXPECT=<<EOF
code
10816
10817
10816
dart: indirect call via PP+0x40 code method.fn_10816
4132980
CALL
EOF
RUN
+18
View File
@@ -0,0 +1,18 @@
NAME=pp-code-resolve-ios
FILE=bins/ios/AuthPass.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -j -O pp+0x68~{pp_slot.resolved_kind}
r2flutter -q -j -O pp+0x68~{pp_slot.resolved_code_index}
r2flutter -q -j -O pp+0x70~{pp_slot.resolved_code_index}
r2flutter -q -j -HHH -l 1100~{snapshots[1].clusters[1028].object_pools[0].entries[11].resolved_code_index}
EOF
EXPECT=<<EOF
code
36399
36400
36399
EOF
RUN
+23
View File
@@ -0,0 +1,23 @@
NAME=pp-code-resolve-main-discarded-and-deferred
FILE=malloc://0x8c
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
# Main Code refs include a discarded entry; the last Code is deferred.
wx 50414421f5f5dcdc84000000000000000200000000000000333063303531636239313932663664363831326265336630623837613633353670726f647563742061726d363420636f6d707265737365642d706f696e746572730082878283800040c483c0c8c081c00060c5818480808080808080808080808080808080808080808080841183118411851186
r2flutter -q -j -O pp+0x10~{pp_slot.resolved_kind}
r2flutter -q -j -O pp+0x10~{pp_slot.resolved_code_index}
r2flutter -q -j -O pp+0x18~{pp_slot.resolved_code_index}
r2flutter -q -j -O pp+0x20~{pp_slot.resolved_code_index}
r2flutter -q -j -O pp+0x28~{pp_slot.resolved_kind}
r2flutter -q -j -O pp+0x28~{=}~resolved_code_index~?
EOF
EXPECT=<<EOF
code
0
1
2
code
0
EOF
RUN
+24
View File
@@ -0,0 +1,24 @@
NAME=pp-collection-cycles-and-map-set-storage
FILE=malloc://0xb4
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
wx 50414421f5f5dcdcac000000000000000200000000000000333063303531636239313932663664363831326265336630623837613633353670726f647563742061726d363420636f6d707265737365642d706f696e746572730082878780800020d781a00040d681840040d5810060d5810000d6810020d6810060c58185a0636f6c6c656374696f6e2d6379636c6584808483838580808480808080848080808084808080808480808511841185118611871188
r2flutter -q -j -xz~{[0].value}
r2flutter -q -j -xz~{[0].refs[0].name}
r2flutter -q -j -xz~{[0].refs[1].name}
r2flutter -q -j -xz~{[0].refs[2].name}
r2flutter -q -j -xz~{[0].refs[3].name}
r2flutter -q -j -xz~{[0].refs[4].name}
r2flutter -q -j -xz~{[0].refs[4].kind}
EOF
EXPECT=<<EOF
collection-cycle
pool=9 index=0 entry=0 pp_off=0x10 leaf=array[1]
pool=9 index=0 entry=1 pp_off=0x18 leaf=array[1]
pool=9 index=0 entry=2 pp_off=0x20 leaf=array[1]
pool=9 index=0 entry=3 pp_off=0x28 leaf=array[1]
pool=9 index=0 entry=4 pp_off=0x30 leaf=array[1]
object_pool.collection
EOF
RUN
@@ -0,0 +1,28 @@
NAME=pp-collection-string-xref-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -AA
axtq @ 0x42ad3~0xdb177
axtq @ 0x4d912~0xdb177
r2flutter -q -AAA
CC. @ 0x19c21c~PP slot +0x5d0 array~?
CC. @ 0x19c21c~contains string "cancel"~?
CC. @ 0x19c21c~contains string "hover"~?
axtq @ 0x42ad3~0x19c21c
axtq @ 0x4d912~0x19c21c
r2flutter -q -r -xz~0x42ad3 0xdb177
EOF
EXPECT=<<EOF
0xdb177
0xdb177
1
1
1
0x19c21c
0x19c21c
ax 0x42ad3 0xdb177
EOF
RUN
+28
View File
@@ -0,0 +1,28 @@
NAME=pp-collection-string-xref-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -AA
axtq @ 0x2ab3a0~0x22d6a1
axtq @ 0x2bbf30~0x22d6a1
r2flutter -q -AAA
CC. @ 0x15f4c~PP slot +0x3d0 array~?
CC. @ 0x15f4c~contains string "cancel"~?
CC. @ 0x15f4c~contains string "hover"~?
axtq @ 0x2ab3a0~0x15f4c
axtq @ 0x2bbf30~0x15f4c
r2flutter -q -r -xz~0x2ab3a0 0x22d6a1
EOF
EXPECT=<<EOF
0x22d6a1
0x22d6a1
1
1
1
0x15f4c
0x15f4c
ax 0x2ab3a0 0x22d6a1
EOF
RUN
+21
View File
@@ -0,0 +1,21 @@
NAME=r2-pp-analysis-discarded-code-android
FILE=bins/android/first/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true -e io.cache=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
# Simulate fewer retained Code objects than instruction entries, with all
# entries before first_entry_with_code. Patches stay in the IO cache.
wx 1e8a @ 0x8f7f
wv4 1311 @ 0x1f558
r2flutter -q -i~?
r2flutter -q -l 2 -i~?
r2flutter -q -AAA
axtq @ 0x2710
EOF
EXPECT=<<EOF
1311
2
0x8b914
EOF
RUN
+21
View File
@@ -0,0 +1,21 @@
NAME=pp-field-resolve-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -j -O pp+0x60~{pp_slot.resolved_kind}
r2flutter -q -O pp+0x60
r2flutter -q -j -O ref:52876~{snapshot.name}
r2flutter -q -j -HHH -l 500~{snapshots[1].clusters[365].object_pools[0].entries[10].resolved_name}
r2flutter -q -AAA
CC. @ 0x1eee60
EOF
EXPECT=<<EOF
field
Platform.isAndroid
Platform.isAndroid
Platform.isAndroid
dart: PP slot +0x60 field Platform.isAndroid
EOF
RUN
+21
View File
@@ -0,0 +1,21 @@
NAME=pp-field-resolve-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -j -O pp+0x120~{pp_slot.resolved_kind}
r2flutter -q -O pp+0x120
r2flutter -q -j -O ref:40563~{snapshot.name}
r2flutter -q -j -HHH -l 500~{snapshots[1].clusters[320].object_pools[0].entries[34].resolved_name}
r2flutter -q -AAA
CC. @ 0xfb3c
EOF
EXPECT=<<EOF
field
Zone._current@4048458
Zone._current@4048458
Zone._current@4048458
dart: PP slot +0x120 field Zone._current@4048458
EOF
RUN
+30
View File
@@ -0,0 +1,30 @@
NAME=pp-field-resolve-patched-owner-and-missing-metadata
FILE=malloc://0xbc
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
wx 50414421f5f5dcdcb4000000000000000200000000000000333063303531636239313932663664363831326265336630623837613633353670726f647563742061726d363420636f6d707265737365642d706f696e746572730082898580800020d7838888900020c180810040c1810060c2830060c5818388666e5f3188666e5f3090746f704c6576656c8380808080808080808080808048c1c4c4c0c0c0c080868084878080c08085808080c080bf868080c0808311881189118a
r2flutter -q -j -O pp+0x10~{pp_slot.resolved_kind}
r2flutter -q -O pp+0x10
r2flutter -q -j -O ref:8~{snapshot.name}
r2flutter -q -O pp+0x18
r2flutter -q -O pp+0x20
r2flutter -q -j -O pp+0x20~{=}~resolved_name~?
wx 87 @ 0xa1
r2flutter -q -O pp+0x10
wx 86 @ 0xa1
r2flutter -q -O pp+0x10 -m custom/obf-map.txt
r2flutter -q -j -O ref:8 -m custom/obf-map.txt~{snapshot.name}
EOF
EXPECT=<<EOF
field
fn_1.fn_0
fn_1.fn_0
topLevel
field
0
fn_0
build.initState
build.initState
EOF
RUN
+17
View File
@@ -0,0 +1,17 @@
NAME=r2-pp-gp-register-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF2
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -A
e anal.gp
e anal.gpseed
f~ PP[0]
EOF2
EXPECT=<<EOF2
0x0022d2d1
x27
0x0022d2d1
EOF2
RUN
@@ -0,0 +1,18 @@
NAME=r2-pp-instance-string-xref-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -AA
axtq @ 0x3d29e~0xdb87f
r2flutter -q -AAA
CC. @ 0x19d630
axtq @ 0x3d29e~0x19d630
EOF
EXPECT=<<EOF
0xdb87f
dart: PP slot +0xcd8 instance | dart: PP slot +0xcd8 contains string "dark"
0x19d630
EOF
RUN
+18
View File
@@ -0,0 +1,18 @@
NAME=r2-pp-instance-string-xref-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -AA
axtq @ 0x2a3300~0x22dd19
r2flutter -q -AAA
CC. @ 0x330ac
axtq @ 0x2a3300~0x330ac
EOF
EXPECT=<<EOF
0x22dd19
dart: PP slot +0xa48 instance | dart: PP slot +0xa48 contains string "dark"
0x330ac
EOF
RUN
+19
View File
@@ -0,0 +1,19 @@
NAME=r2-pp-null-bool-annotations-ios
FILE=bins/ios/AuthPass.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF2
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -AAA
CC.@0x3175ac
CC.@0x31752c
CC.@0xfe68
CC.@0x1012c
EOF2
EXPECT=<<EOF2
dart: true
dart: false
dart: null
dart: compare with null
EOF2
RUN
@@ -0,0 +1,15 @@
NAME=r2-pp-shifted-string-xref-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -AAA
CC. @ 0x178c70
axtq @ 0x51746~0x178c70
EOF
EXPECT=<<EOF
dart: PP slot +0xb5f8 string "Unexpected state: "
0x178c70
EOF
RUN
+15
View File
@@ -0,0 +1,15 @@
NAME=r2-pp-shifted-string-xref-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -AAA
CC. @ 0x44604
axtq @ 0x27af40~0x44604
EOF
EXPECT=<<EOF
dart: PP slot +0xa590 string "callOnHover"
0x44604
EOF
RUN
+55
View File
@@ -0,0 +1,55 @@
NAME=r2-pp-slot-function-resolve-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF2
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -AAA
CC.@0xf63c
EOF2
EXPECT=<<EOF2
dart: PP slot +0x15e0 function method.Native._anon_closure
EOF2
RUN
NAME=r2-pp-slot-function-xref-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF2
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -AAA
axf @ 0xf63c~method.Native._anon_closure
EOF2
EXPECT=<<EOF2
DATA 0xf6e4 method.Native._anon_closure
EOF2
RUN
NAME=r2-pp-slot-function-resolve-authpass
FILE=bins/ios/AuthPass.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF2
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -AAA
CC.@0xfe88
EOF2
EXPECT=<<EOF2
dart: PP slot +0xecb0 function method.MapBase._anon_closure
EOF2
RUN
NAME=r2-pp-indirect-call-aligned-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF2
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -AAA
CC.@0xf6d0
EOF2
EXPECT=<<EOF2
dart: indirect call via PP+0x1600 canonical_set
EOF2
RUN
@@ -0,0 +1,13 @@
NAME=r2-pp-string-dataref-xref-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF2
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -AA
axt 0x177f3~0xdc8f7[1]
EOF2
EXPECT=<<EOF2
0xdc8f7
EOF2
RUN
+23
View File
@@ -0,0 +1,23 @@
NAME=record-values-android
FILE=bins/android/mafia/libapp.so
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -j -O ref:158051~{snapshot.kind}
r2flutter -q -j -O ref:158051~{snapshot.complete}
r2flutter -q -j -O ref:158051~{snapshot.shape}
r2flutter -q -j -O ref:158051~{snapshot.length}
r2flutter -q -j -O ref:158051~{snapshot.fields[0].ref}
r2flutter -q -j -O ref:158051~{snapshot.fields[1].value.name}
r2flutter -q -j -O ref:158051~{snapshot.fields[1].value.fields[2].value.value}
EOF
EXPECT=<<EOF
record
true
2
2
1001
XmlAttributeType
DOUBLE_QUOTE
EOF
RUN
+14
View File
@@ -0,0 +1,14 @@
NAME=record-values-malformed
FILE=malloc://0xfd
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
wx 50414421f5f5dcdcf5000000000000000200000000000000333063303531636239313932663664363831326265336630623837613633353670726f647563742061726d363420636f6d707265737365642d706f696e746572730082898280800020cf82c1be0060d08580828281018180818384020084868381880181838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383
r2flutter -q -j -O ref:6~{snapshot.kind}
r2flutter -q -j -O ref:6~{snapshot.complete}
EOF
EXPECT=<<EOF
record
false
EOF
RUN
+34
View File
@@ -0,0 +1,34 @@
NAME=record-values-synthetic
FILE=malloc://0xfd
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
wx 50414421f5f5dcdcf5000000000000000200000000000000333063303531636239313932663664363831326265336630623837613633353670726f647563742061726d363420636f6d707265737365642d706f696e746572730082898280800020cf82c1be0060d08580828281018180828384020084868381880181838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383
r2flutter -q -j -O ref:5~{snapshot.complete}
r2flutter -q -j -O ref:5~{snapshot.length}
r2flutter -q -j -O ref:6~{snapshot.fields[0].value.value}
r2flutter -q -j -O ref:6~{snapshot.fields[1].value.value}
r2flutter -q -j -O ref:7~{snapshot.shape}
r2flutter -q -j -O ref:7~{snapshot.field_names_index}
r2flutter -q -j -O ref:7~{snapshot.fields[0].value.fields[1].value.value}
r2flutter -q -j -O ref:8~{snapshot.fields[0].value.cycle}
r2flutter -q -j -O ref:9~{snapshot.length}
r2flutter -q -j -O ref:9~{snapshot.values_truncated}
r2flutter -q -j -O ref:9~{snapshot.fields[127].value.value}
r2flutter -q -j -O ref:9~{=}~name = ~?
EOF
EXPECT=<<EOF
true
0
1
-2
65538
1
-2
true
129
true
1
128
EOF
RUN
+20
View File
@@ -0,0 +1,20 @@
NAME=record-values-uncompressed
FILE=malloc://0x100
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
wx 50414421f5f5dcdcf8000000000000000200000000000000333063303531636239313932663664363831326265336630623837613633353670726f647563742061726d3634206e6f2d636f6d707265737365642d706f696e746572730082898280800020cf82c1be0060d08580828281018180828384020084868381880181838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383838383
r2flutter -q -j -O ref:6~{snapshot.kind}
r2flutter -q -j -O ref:6~{snapshot.complete}
r2flutter -q -j -O ref:6~{snapshot.length}
r2flutter -q -j -O ref:6~{snapshot.fields[1].value.value}
r2flutter -O ref:6~kind=record
EOF
EXPECT=<<EOF
record
true
2
-2
ref=6 kind=record cid=67 shape=2 length=2 complete=true
EOF
RUN
+1 -1
View File
@@ -25,7 +25,7 @@ map
true
array
48
129
1
instance
SemanticsAction
1
+11 -11
View File
@@ -56,7 +56,7 @@ L ../src/r2/core_flutter.so
r2flutter -q -j -xz~{[0]}
EOF
EXPECT=<<EOF
{"ref":10404,"len":25,"value":"useShouldInterceptRequest","category":"lib","two_byte":false,"canonical":true,"addr":302465,"refs":[{"obj":195985,"type":"other","kind":"object_pool.entry","name":"pool=195985 index=0 entry=44440 pp_off=0x56cd0"}]}
{"ref":2429,"len":15,"value":"<optimized out>","category":"app","two_byte":false,"canonical":true,"addr":2133,"refs":[{"obj":195985,"type":"other","kind":"object_pool.entry","name":"pool=195985 index=0 entry=7053 pp_off=0xdc78"}]}
EOF
RUN
@@ -68,9 +68,9 @@ L ../src/r2/core_flutter.so
r2flutter -q -z~:0..3
EOF
EXPECT=<<EOF
useShouldInterceptRequest
There was an error but it could not be loaded from IsarCore.
exercise
<optimized out>
\x1a
4
EOF
RUN
@@ -82,10 +82,10 @@ L ../src/r2/core_flutter.so
r2flutter -q -r -x -z~:0..4
EOF
EXPECT=<<EOF
iz+ 0x00049d81 25
f str.useShouldInterceptRequest.0x49d81 25 @ 0x00049d81
Cs8 25 @ 0x00049d81
ax 0x49d81 0x3dbe24
iz+ 0x00000855 15
f str._optimized_out_.0x855 15 @ 0x00000855
Cs8 15 @ 0x00000855
ax 0x855 0x392dcc
EOF
RUN
@@ -97,8 +97,8 @@ L ../src/r2/core_flutter.so
r2flutter -qz~:0..3
EOF
EXPECT=<<EOF
useShouldInterceptRequest
There was an error but it could not be loaded from IsarCore.
exercise
<optimized out>
\x1a
4
EOF
RUN
+41
View File
@@ -0,0 +1,41 @@
NAME=r2-strings-config-mafia
FILE=bins/android/mafia/libapp.so
CMDS=<<EOF
L ../src/r2/core_flutter.dylib
L ../src/r2/core_flutter.so
e r2flutter.str.limit=3
r2flutter -q -zz
?e --
e r2flutter.str.filter=^https?://
r2flutter -q -zz
?e --
e r2flutter.str.filter=
e r2flutter.str.minlen=41
e r2flutter.str.maxlen=42
r2flutter -zz
?e --
e r2flutter.str.minlen=0
e r2flutter.str.maxlen=0
e r2flutter.str.limit=2
e r2flutter.str.filter=^ab
r2flutter -j -zz
EOF
EXPECT=<<EOF
<optimized out>
Handle
MonomorphicSmiableCall
--
http://www.w3.org/XML/1998/namespace
http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd
https://www.youtube.com/watch?v=
--
0x0004a5e8 42 :lib "_createBuiltInForegroundPainters@401245603"
0x0004b7d4 41 :lib "package:qr_flutter/src/qr_image_view.dart"
0x0004bab3 42 :lib "expected-closing-tag-but-got-right-bracket"
--
[{"ref":12,"len":8,"value":"abstract","category":"lib","two_byte":false,"canonical":true,"addr":2307},{"ref":209,"len":8,"value":"absolute","category":"lib","two_byte":false,"canonical":true,"addr":5339}]
EOF
RUN
+18
View File
@@ -0,0 +1,18 @@
NAME=strings-instance-pool-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -z~^detached$
r2flutter -q -z~^dark$
r2flutter -xz~object_pool.instance_field~pp_off=0x4780
r2flutter -q -r -xz~0x19649 0xdf327
EOF
EXPECT=<<EOF
detached
dark
# object_pool.instance_field other pool=54352 index=0 entry=2286 pp_off=0x4780 field=2 [ref=54352] @ 0xdf327
ax 0x19649 0xdf327
EOF
RUN
+18
View File
@@ -0,0 +1,18 @@
NAME=strings-instance-pool-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
r2flutter -q -z~^detached$
r2flutter -q -z~^dark$
r2flutter -xz~object_pool.instance_field~pp_off=0x38b8
r2flutter -q -r -xz~0x26fa30 0x230b89
EOF
EXPECT=<<EOF
detached
dark
# object_pool.instance_field other pool=41741 index=0 entry=1813 pp_off=0x38b8 field=1 [ref=41741] @ 0x230b89
ax 0x26fa30 0x230b89
EOF
RUN
+2 -2
View File
@@ -10,8 +10,8 @@ EXPECT=<<EOF
# class Pointer (size=32)
# type_params: 1
"td struct dart_Pointer { };"
# method 0x00000000 get:hashCode (GetterFunction)
# method 0x00000000 == (RegularFunction)
# method 0x00115f2c get:hashCode (GetterFunction)
# method 0x001299fc == (RegularFunction)
# class NativeType (size=16)
EOF
RUN
+4 -4
View File
@@ -8,8 +8,8 @@ EOF
EXPECT=<<EOF
class Pointer (size=32)
methods:
0x00000000 get:hashCode (GetterFunction)
0x00000000 == (RegularFunction)
0x00c6ab64 get:hashCode (GetterFunction)
0x00d8bde8 == (RegularFunction)
class NativeType (size=16)
class NativeFunction (size=16)
EOF
@@ -27,8 +27,8 @@ EXPECT=<<EOF
# class Pointer (size=32)
# type_params: 1
"td struct dart_Pointer { };"
# method 0x00000000 get:hashCode (GetterFunction)
# method 0x00000000 == (RegularFunction)
# method 0x00c6ab64 get:hashCode (GetterFunction)
# method 0x00d8bde8 == (RegularFunction)
# class NativeType (size=16)
EOF
RUN
+14
View File
@@ -0,0 +1,14 @@
NAME=xrefs-discarded-code-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true -e io.cache=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
# Mark all table rows as lacking retained Code metadata; instructions remain.
wv4 11017 @ 0x12c998
r2flutter -q -x~0x1b675c~0xc7b
EOF
EXPECT=<<EOF
code code.string 0x1b675c -> 0xc7b
EOF
RUN
+15
View File
@@ -0,0 +1,15 @@
NAME=xrefs-full-coverage-android
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
# Instruction 389 in IT entry 808, followed by IT entry 10906.
r2flutter -q -x~0x1b675c~0xc7b
r2flutter -q -x~0x3f4908~0x23a0b
EOF
EXPECT=<<EOF
code code.string 0x1b675c -> 0xc7b
code code.string 0x3f4908 -> 0x23a0b
EOF
RUN
+15
View File
@@ -0,0 +1,15 @@
NAME=xrefs-full-coverage-ios
FILE=bins/ios/Runner.app/Frameworks/App.framework/App
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
# Instruction 107 in IT entry 2642, followed by IT entry 4235.
r2flutter -q -x~0x929d0~0x2a1600
r2flutter -q -x~0xea070~0x2a1600
EOF
EXPECT=<<EOF
code code.string 0x929d0 -> 0x2a1600
code code.string 0xea070 -> 0x2a1600
EOF
RUN
+15
View File
@@ -0,0 +1,15 @@
NAME=xrefs-instructions-end
FILE=bins/android/w0rdle/libapp.so
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true -e io.cache=true
CMDS=<<EOF
L ../src/r2/core_flutter.so
L ../src/r2/core_flutter.dylib
# Load the same PP string in the last function and just outside the image.
wx 602f40f9 @ 0x3f8814
wx 602f40f9 @ 0x3f8870
r2flutter -q -x~0x3f8814,0x3f8870~0x23a0b
EOF
EXPECT=<<EOF
code code.string 0x3f8814 -> 0x23a0b
EOF
RUN
+3 -3
View File
@@ -8,8 +8,8 @@ EOF
EXPECT=<<EOF
metadata class.name class Pointer [ref=36652] -> string Pointer [ref=151] @ 0x1b24d0
metadata class.library class Pointer [ref=36652] -> library library#41733 [ref=41733]
metadata method.owner method Pointer.get:hashCode [ref=31064] -> class Pointer [ref=36652]
metadata method.name method Pointer.get:hashCode [ref=31064] -> string get:hashCode [ref=7217] @ 0x2b0230
metadata method.owner method Pointer.get:hashCode [ref=31064] @ 0x115f2c -> class Pointer [ref=36652]
metadata method.name method Pointer.get:hashCode [ref=31064] @ 0x115f2c -> string get:hashCode [ref=7217] @ 0x2b0230
EOF
RUN
@@ -21,7 +21,7 @@ L ../src/r2/core_flutter.so
r2flutter -j -l 3 -x
EOF
EXPECT=<<EOF
[{"kind":"class.name","origin":"metadata","src":{"type":"class","name":"Pointer","ref":36652},"dst":{"type":"string","name":"Pointer","ref":151,"addr":1778896}},{"kind":"class.library","origin":"metadata","src":{"type":"class","name":"Pointer","ref":36652},"dst":{"type":"library","name":"library#41733","ref":41733}},{"kind":"method.owner","origin":"metadata","src":{"type":"method","name":"Pointer.get:hashCode","ref":31064},"dst":{"type":"class","name":"Pointer","ref":36652}}]
[{"kind":"class.name","origin":"metadata","src":{"type":"class","name":"Pointer","ref":36652},"dst":{"type":"string","name":"Pointer","ref":151,"addr":1778896}},{"kind":"class.library","origin":"metadata","src":{"type":"class","name":"Pointer","ref":36652},"dst":{"type":"library","name":"library#41733","ref":41733}},{"kind":"method.owner","origin":"metadata","src":{"type":"method","name":"Pointer.get:hashCode","ref":31064,"addr":1138476},"dst":{"type":"class","name":"Pointer","ref":36652}}]
EOF
RUN
+1 -4
View File
@@ -3,7 +3,7 @@ FILE=bins/android/first/libapp.so
ARGS=-NN -e bin.relocs.apply=true
CMDS=<<EOF
.!sh -c "p=../src/r2/core_flutter.dylib; [ -f \"\$p\" ] || p=../src/r2/core_flutter.so; printf \"L %s\\n\" \"\$p\""
r2flutter -AAA
r2flutter -qAAA
f~dart.class
s 0x66a70
EOF
@@ -295,7 +295,4 @@ EXPECT=<<EOF
0x00008e20 0 dart.class.MonomorphicSmiableCall
0x00008e90 0 dart.class.Handle
EOF
EXPECT_ERR=<<EOF
INFO: Flutter analysis: 1311 functions, 4731 calls, 0 fields, 9 classes, 0 types, 42 strings, 2912 PP refs
EOF
RUN
+6 -2
View File
@@ -9,7 +9,9 @@ r2flutter
EOF
EXPECT=<<EOF
Usage: r2flutter [qjr*] <action>
| r2flutter -A[AA] analyze dart snapshot and apply flags/comments
| r2flutter -A apply flags, function names and signatures
| r2flutter -AA also seed anal.gp and apply ObjectPool xrefs
| r2flutter -AAA also run the full register-tracking scan (slow)
| r2flutter -c[jr*] dump classes
| r2flutter -C apply Dart classes, fields, methods and types
| r2flutter -D prof override Dart snapshot profile by hash or version
@@ -35,7 +37,9 @@ Usage: r2flutter [qjr*] <action>
Modifiers: q=quiet, j=json, r/*=r2 commands
===
Usage: r2flutter [qjr*] <action>
| r2flutter -A[AA] analyze dart snapshot and apply flags/comments
| r2flutter -A apply flags, function names and signatures
| r2flutter -AA also seed anal.gp and apply ObjectPool xrefs
| r2flutter -AAA also run the full register-tracking scan (slow)
| r2flutter -c[jr*] dump classes
| r2flutter -C apply Dart classes, fields, methods and types
| r2flutter -D prof override Dart snapshot profile by hash or version