> For the complete documentation index, see [llms.txt](https://docs.hex-rays.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hex-rays.com/release-notes/9_5beta.md).

# IDA 9.5 Beta

![](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-3e22a89557b4fc5fbef818a1d1c911a1cbea4e08%2Fbeta95.png?alt=media)

## IDA 9.5 Beta

Welcome to the IDA 9.5 Beta Release, and thank you to all our beta testers for joining us! Below are the key highlights and changes introduced in this beta version.

{% hint style="info" %}
**Independent add-on release cycles**

Starting with 9.5, the Malware Analysis, Teams, Lumina, Assist and IDA MCP add-ons are decoupled from the IDA core release cycle. Each is versioned and shipped independently, so fixes, new capabilities, and updated signature sets land as soon as they're ready instead of waiting on the next IDA release. Add-ons update in place against your installed IDA.
{% endhint %}

{% hint style="info" %}
**Share your feedback**

Spotted a bug or have a suggestion for the beta? Let us know and contribute to IDA evolution through one of the following channels:

* [Hex-Rays Support](https://support.hex-rays.com) (*Early access* feedback form),
* Email: <support@hex-rays.com>, or
* Slack: Join the discussion in our dedicated beta channel. If you didn’t receive the invitation link, [contact us](mailto:support@hex-rays.com).
  {% endhint %}

## What's in this release

<table data-view="cards"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><a href="#highlights"><strong>Highlights</strong></a></td><td>The marquee features: the new Dalvik, TriCore and Hexagon decompilers, decompiler bitfield support, a much stronger AVX/SSE pipeline, the Apple kernelcache loader, verbatim names, FLIRT 2.0, smarter switch-case recovery, and recursive "Create C file" export.</td></tr><tr><td><a href="#hll"><strong>Higher-Level Language Support</strong></a></td><td>Loading Go binaries with corrupt or obfuscated metadata, and the Rust ABI extended to ARM[64], MIPS, PPC and RISC-V.</td></tr><tr><td><a href="#decompiler"><strong>Decompiler</strong></a></td><td>Jump to function-pointer targets, register-variable splitting, scattered pairs, better x87 handling, stripped-Swift recovery, and many output-quality improvements.</td></tr><tr><td><a href="#disassembler"><strong>Disassembler</strong></a></td><td>Register values tracked across loops, ARC/Hexagon/MIPS R6 work, more Armv9 extensions, broad game-console support (PS3, Xbox 360, Wii U, PSP), and a new WebAssembly loader and disassembler.</td></tr><tr><td><a href="#analysis"><strong>Analysis &#x26; Kernel</strong></a></td><td>Correct exception-handling stack levels, robust try blocks, and guards against pathological binaries.</td></tr><tr><td><a href="#uefi"><strong>UEFI</strong></a></td><td>A new UEFI plugin and loader that analyze whole firmware images and make known protocol calls decompile to readable code.</td></tr><tr><td><a href="#typesystem"><strong>Type System</strong></a></td><td>Clang is the new default parser, with version-matched XNU type libraries for Apple Silicon macOS kernels.</td></tr><tr><td><a href="#debuginfo"><strong>Debug Info, Demangling and Exception Handling</strong></a></td><td>Swift 6 demangling, better DWARF and PDB handling, and Rust type recovery.</td></tr><tr><td><a href="#uiux"><strong>UI &#x26; UX</strong></a></td><td>Qt 6.12 LTS, a new HTML listing renderer, a tightly-linked Pathfinder and Xref graph, and a reworked quick filter.</td></tr><tr><td><a href="#flirt"><strong>FLIRT &#x26; FLAIR</strong></a></td><td>FLIRT 2.0 signatures, byte-range patterns, and refreshed MSVC runtime coverage.</td></tr><tr><td><a href="#performance"><strong>Performance &#x26; Resource Consumption</strong></a></td><td>Less memory and fewer stalls on large binaries: DWARF, dyld shared caches, RTTI and the decompiler.</td></tr><tr><td><a href="#sdk"><strong>Configuration, IDAPython, SDK &#x26; API</strong></a></td><td>Installation manifests for every extension kind, plus new listing-export, class, license-inspection and synthetic-string APIs.</td></tr><tr><td><a href="#network"><strong>Network &#x26; Security</strong></a></td><td>Clear answers when a license, Lumina or Vault server misbehaves, no more freezes, and hardened Linux builds.</td></tr></tbody></table>

## Highlights <a href="#highlights" id="highlights"></a>

### New Decompiler: Dalvik

IDA now decompiles Android DEX bytecode into Java pseudocode. It is built on a typed model of the DEX file, so a class, a field, a method and a parameter are all real, renameable, retypable entities, and an edit to any of them propagates through the pseudocode.

* a class view lists the program's classes and shows each declaration with its fields and methods; it offers pseudocode hints and "Move function to folder", and Ctrl+Shift+F6 or a Ctrl+double-click in the class tree opens another class view
* in a multidex application a call reaches the method body in the other dex file, and a virtual call also references the overrides in the subclasses
* `try`/`catch` blocks are reconstructed from the DEX exception tables
* methods with optimized (odex) bytecode are decompiled too
* obfuscated names are recovered wherever the file still carries them: Kotlin metadata, serializer annotations and DEX debug info

The class view is where you work: Tab switches between the disassembly and the class view, and it offers the pseudocode editing actions — comments, renaming locals, arguments, labels, fields and methods, "Set type" in Java syntax (register widths are checked), collapse/uncollapse, invert if, hide casts, map/unmap variable, local cross-references and synchronization with the other views.

The output reads like the source:

* string concatenation is shown as `"a" + b` instead of the `StringBuilder.append()` chain that javac, kotlinc and d8 generate
* nested classes print as `Outer.Inner`; declarations show generics (from `dalvik.annotation.Signature`), annotations as `@Foo(...)`, and anonymous classes as `new Type() { ... }`
* method parameters are named from the DEX annotations
* calls use the callee's declared type, so retyping a method updates the pseudocode of its callers, and array arguments are no longer degraded to `Object`
* `try`/`catch`/`finally` is reconstructed by dominance analysis: nested blocks, catch-all handlers, `finally` blocks that end in `return` or `goto`, and `synchronized` blocks with several exits

For scripts and plugins, the new language-neutral class API (`get_classes()`, `get_class_info()`, `render_class()`, `render_member()`, C++ and IDAPython) has Dalvik as its first backend. Edits made in the class view do not raise the Hex-Rays pseudocode events (variable renamed/retyped, comment changed, ...).

**Limitations:** `try`-with-resources is not reconstructed (the output is longer but correct), and the output is Java, not Kotlin.

### New Decompiler: TriCore

Infineon TriCore: the new `hextricore` plugin decompiles TriCore code. It supports `eabi` and `Tasking` ABI families.

### New Decompiler: Hexagon

Qualcomm Hexagon (QDSP6): the new `hexqdsp6` plugin decompiles DSP code. It models packet semantics (parallel reads, `.new` values, predication), hardware loops, compound branches and jump tables, floating point, and the scalar SIMD instructions; HVX vector and system instructions appear as intrinsics.

* every instruction of a packet reads its registers as of the packet start, `.new`/`.cur` operands see the packet's own results, and predicated instructions become conditional blocks
* variadic functions are recognized
* intrinsics use clang's `__builtin_HEXAGON_*` names, so their semantics can be looked up in `hexagon_protos.h`
* HVX vectors (`V0`–`V31`, `Q0`–`Q3`) are modeled as vector registers, and system, guest, cache and supervisor instructions appear as intrinsics

### Decompiler Support for Bitfields

Accesses to C [bitfield members](https://en.cppreference.com/c/language/bit_field) are shown as member accesses instead of shift and mask arithmetic: `(*(_DWORD *)&s >> 3) & 7` reads as `s.field`, and `*p = *p & 0xFFFFFF07 | (v << 3) & 0xF8` as `p->field = v` (once the types are correctly defined and applied). It covers every architecture supported by the decompiler, including the dedicated extract/insert instructions of ARM64, PPC, MIPS and RISC-V. It is enabled by default but can be turned off with "Decompile bitfield accesses" in **Edit > Plugins > Hex-Rays Decompiler Options > Options 2**

Most patterns used by popular compilers are handled. For example, the non-obvious xor toggle from MSVC:

```c
struct s4 { unsigned a : 4; unsigned b : 4; unsigned rest : 24; };
void inc_a(struct s4 *p) { p->a++; }
// 9.4
 *(_DWORD *)p ^= ((unsigned __int8)*(_DWORD *)p ^ (unsigned __int8)(*(_DWORD *)p + 1)) & 0xF;
// 9.5
++p->a;
```

Other recognized shapes:

* reads scaled by a power of two (the mask gets scaled too)
* fields extracted from a copy of the unit loaded into a register
* a field in the top bit tested by a signed comparison,
* an access narrower than the unit

```c
// 9.4
if ( ControlPc >= ((*((_DWORD *)v1 + 1) >> 6) & 0xFFFFFC) + v1->FuncStart )
v16 = *((_DWORD *)FunctionEntry + 1);
if ( (v16 & 0xC0000000) == 0x80000000 )
if ( *((int *)this->m_pDevice + 5442) < 0 )
if ( (*((_BYTE *)Material + 720) & 1) == 0 )
// 9.5
if ( ControlPc >= 4 * v7->FuncLen + v7->FuncStart )
if ( FunctionEntry->Flags == 2 )
if ( this->m_pDevice->m_TimingCaptureActive != 0 )
if ( Material->bUseOneLayerDistortion == 0 )
```

A store that packs several fields of one unit decomposes into per-field assignments; the same field compared or combined across two objects shows both members; a masked compound update with a variable operand folds:

```c
// 9.4
U = C | (v1 << s1) | (v2 << s2);
(a.type ^ b.type) & MASK
U ^= V & MASK
// 9.5
x.f1 = v1; x.f2 = v2;
a.f ^ b.f
x.f ^= V
```

The bit allocation order defauls to the same direction as byte order, but can be fliped for specific types. This is a common situation in Xbox 360 binaries, which use litte-endian bitfield order for GPU registers or some kernel structures inherited from the Windows kernel. If needed, `#pragma bitfield_order(lsb_to_msb)` or `__invbf` specifier can be used to mark such types.

When PDB with full type info is available, it is used to detect the bit order:

```c
// 9.4: LSB order (wrong default for BE binary)
struct IMPORT_OBJECT_HEADER { 
  ... 
  unsigned __int16 Reserved : 11;
  unsigned __int16 NameType : 3;
  unsigned __int16 Type     : 2; 
};
// 9.5: same order as winnt.h declares it
struct IMPORT_OBJECT_HEADER { 
  ... 
  unsigned __int16 Type : 2;
  unsigned __int16 NameType : 3;
  unsigned __int16 Reserved : 11;
};
```

### Better SSE/AVX/AVX2/AVX-512 Support in the Disassembler and Decompiler

* x86/x64: loads and stores wider than 16 bytes are shown as plain C assignments instead of SSE/AVX load/store intrinsics, and `punpcklqdq` is shown as a move into the high half, so "Split expression" can split it

Where AVX code used to decompile to `__asm` blocks, the new `avxlifter` plugin turns AVX, AVX2, AVX-512 (F/CD/BW/DQ/VBMI/VNNI/BF16/FP16/VL) and VMX instructions into native microcode where the decompiler can reason about them, and into `_mm*_…` intrinsics on `__m128`/`__m256`/`__m512` values otherwise — masked EVEX merge/zero forms, gather/scatter, compress/expand and the opmask `k` registers included.

* packed and/or/xor/andnot become C operators, so sign-flip and abs masks read as `a ^ signmask` and `a & absmask`, and `vxorpd x, x, x` is `0.0`
* scalar FMA and min/max become C math (`fminf`, `fmaxf`) instead of `_mm_*_ss` intrinsics
* intrinsics without side effects are marked pure, so dead vector computations are removed
* XMM, YMM and ZMM are modeled as views of one register, with legacy-SSE writes leaving the upper part intact; bogus undefined YMM variables are gone
* vector unions gain `__int128` members, which removes `*(_OWORD *)` casts
* SIMD loads, stores, `memcpy`/`memmove` and structure copies are plain assignments; no `_mm_loadu_si128`/`_mm256_storeu_ps` remain
* `tzcnt` is lifted to `__tzcnt()`
* string literals copied piecewise with `movups`/`movsd`/`mov`/`movzx`, UTF-16 and MSVC's mixed-width copies included, are recognized. This is analysis, not lifting, so it works without the plugin
* functions that align their frame pointer (`and rbp, -32`, typical for AVX code) have stack variables again, instead of `&v3 & 0xFFFFFFFFFFFFFFE0`

### Apple Kernel Cache Loader

IDA 9.5 does for Apple kernelcaches what 9.4 did for dyld shared caches: a kernelcache is a collection of KEXTs, and IDA now treats it as one rather than as a single large Mach-O. A linked kernelcache — a system or auxiliary one — is handled together with the boot KC it references, as one coherent set: a single layout, with symbols and references resolved across the link.

* a **KC Index** widget lists the KEXTs of every collection in play, filterable by the one they came from, and maps them on demand — the kernel up front, the rest as you reach them
* the C++ runtime is reconstructed from `OSMetaClass` — the class hierarchy, the virtual methods with their full signatures, the metaclass vtables — and `OSDynamicCast` results, `kalloc_type` descriptors and typed allocations are typed against the XNU type library matching the cache's OS version
* **Locate > Symbol / String / Address** search the whole cache straight from the file, so a KEXT you never loaded is searched like any other, in any collection of the set; and a string search still works on a stripped cache, where there are no symbol tables at all
* the Functions list holds a folder per KEXT or cache image, nested by bundle id (`com/apple/iokit/...`); `FUNC_FOLDER_FORMAT` in `kcu.cfg`/`dscu.cfg` sets the layout, and `""` keeps the list flat
* an example plugin extracts a KEXT or a dyld cache image to a standalone Mach-O ("Extract Mach-O image to file..." in the KC and DSC Index, Ctrl+Alt+Shift+M). The result can be analyzed but not run: it carries no rebase or bind information

### Verbatim Function and Type Names

Modern languages (Rust, Go, Swift, heavily-templated C++) name things with characters that are not valid C identifiers. IDA no longer garbles those into an ASCII-safe form: symbol, type, and member names are now kept verbatim, as they come from symbols, demanglers, and debug info.

* new databases display demangled names by default
* qualified names such as `A::B::C` highlight, select, and cross-reference as a single unit — in disassembly, pseudocode, and printed prototypes
* FLIRT signatures can carry original (unmangled) names, and Go/Rust/Swift naming is honored end to end
* non-C type and member names round-trip faithfully through the Edit-type dialog
* the classic behavior stays available per database via the `GarbleNames` policy (frozen at database creation); existing databases keep their current names

IDA used to replace every character that is not valid in a C identifier with `_`. Types could not be found by their real names, and Rust, Go and Swift binaries read poorly:

```c
// 9.4
__core::fmt::ArgumentV1_
struct mut_ref_dyn_core::fmt::Write
// 9.5
&[core::fmt::ArgumentV1]
struct &mut dyn core::fmt::Write
```

* a name that is not valid C is quoted with backticks when you edit it, and the parsers unquote it — in the Local Types editor, "Set type", the prototype editor and the decompiler's retyping dialogs, with both the clang and the legacy parser. Go's `[]string` and `interface {}` are accepted as type names and highlight as one unit in the pseudocode
* Alt+click highlights only the component under the cursor, e.g. to copy the class part of `A::B::method`
* where a type has a prettified name, the Types window shows and filters on it, hovering shows the full raw name, the raw name behind it is painted translucent, and Jump Anywhere finds the type by either name
* `DemangleNames` in `ida.cfg` now defaults to 5, so new databases show demangled names as names; on ARM, imports honor the setting too
* `GarbleNames` in `ida.cfg` is a bit mask: `0x1`/`0x2` garble symbol names in storage/display, `0x4`/`0x8` do the same for type and member names; the default 0 keeps everything verbatim

**Migration:** the policy is fixed when a database is created. Databases made before 9.5 keep garbling, so their names do not change under existing scripts.

### FLIRT 2.0

Classic FLIRT recognizes a library function from its bytes. The target of a call inside it is relocated by the linker, so FLIRT treats those bytes as a wildcard and forgets what they pointed to — and a helper that has no reliable signature of its own stays unnamed:

```c
void library_function()
{
  hidden_helper();   // call ?? ?? ?? ??  -- FLIRT 1 cannot name this
}
```

FLIRT 2.0 signatures (format v11) also record what each library module refers to. Once `library_function` is matched and its call lands at a certain address, IDA knows the function there is `hidden_helper`. After auto-analysis, a deferred pass names the functions reached from recognized code this way, and uses the same evidence to choose between byte-identical candidates.

Correctly named functions in a stripped, statically linked sqlite3:

| Runtime        |  9.4 |  9.5 |
| -------------- | ---: | ---: |
| glibc amd64    | 1279 | 1846 |
| glibc i386     | 1424 | 1826 |
| glibc arm64    | 1434 | 1815 |
| glibc armhf    |  776 | 1204 |
| glibc riscv64  |  288 |  933 |
| glibc s390x    | 1398 | 1739 |
| MSVC /MT x64   |  565 |  698 |
| MSVC /MT x86   |  458 |  561 |
| MSVC /MT arm64 |    0 |  753 |
| MSVC /MT arm   |    0 |  622 |

* 32-bit binaries of VC 14.39–14.52 are recognized, and the ARM and ARM64 MSVC runtime signatures cover VC11 through VC 14.52
* `main`/`wmain` and `WinMain`/`wWinMain` are told apart from evidence in the binary; startup signatures name the functions and data their entry module references (`___xc_a`, `__commode`, `__fmode`, ...)
* signatures can carry original, unmangled names: the Go runtime signatures keep `runtime.(*mheap).alloc` (the old mangled ones ship as `*_legacy.sig`)
* signatures load faster (bulk and buffered reads)

**Migration:** sigmake now always writes v11. IDA 9.5 reads older `.sig` files, but IDA 9.4 and earlier reject v11, so signatures built with the 9.5 FLAIR tools do not load in 9.4.

### More Precise Decompiler-Based Switch-Case Recovery

* switches that the compiler split across a binary-search dispatch are put back together: a switch nested under an equality or range guard is merged into its parent, and two switches separated by such a guard are combined into one
* a jump table built on a pivot-subtracted selector (`switch (x - C)`) is rebased onto the original value, so the real case labels are recovered
* switches are recovered better from if-chains, including dispatch trees whose cases fall through, and getopt-style trees whose arms leave through the enclosing loop
* cases are sorted by value, cases sharing a body are merged, and a case that only jumps into another case is folded into it

Compilers lower a sparse switch as a binary-search tree of comparisons, often against a pivot-subtracted copy of the selector, with the case bodies sharing tails through `goto`. All of that used to survive into the output. The recovery now runs at both levels: a microcode pass puts the jump table back on the original selector, and ctree passes fuse the fragments and restore the labels.

Shared case tails render as fall-through:

```c
// 9.4                        // 9.5
case 0u:                      case 0u:
  result = 1;                   result = 1;
  goto LABEL_3;               case 1u:
case 1u:                        ++result;
LABEL_3:                      case 2u:
  ++result;                     ++result;
  goto LABEL_4;               case 3u:
case 2u:                        ++result;
LABEL_4:                        break;
  ++result;
  ...
```

A jump table built on a pivot-subtracted selector dispatches on the same value as the surrounding comparisons again, so the fragments fuse and the real labels come back.

Dispatch trees whose case arms assign something and flow on into a shared tail are merged too — the commonest shape of all, and what makes a getopt loop mergeable. That is done only while the arm's original successor is the continuation kept after the merged switch, so the recovered switch computes what the original code did.

On every architecture — x86, ARM, MIPS, RISC-V, PPC, ARC, V850 and Dalvik — the decompiler now finds jump tables with its own data-flow analysis on the microcode instead of reusing the disassembler's switch information. Switches the disassembler missed ("switch analysis failed") are recovered, identical switches are merged, and many that used to decompile wrong are now correct:

```c
// 9.4
if ( v67 <= 8 )
  switch ( (unsigned int)(a3 + 7) >> 3 ) { ... }
// 9.5
switch ( v67 ) { ... }
```

* jump tables made of branch instructions (ARM `ADDLS PC, PC, R3,LSL#2` followed by `B case_n`, PPC/GHS tables) are recognized as switches, and Dalvik `packed-switch`/`sparse-switch` are built from their payload
* when the compiler reuses the selector's register for an offset copy (`v = x - C`), the comparisons are rewritten against the original variable and the dead offset chain is removed; recovered case labels keep their number format (enum, hex, char)
* where no range check can be found, the recovered switch shows `default: abort()`

### "Create C file" Decompiles a Function Together with Its Callees

**File > Produce file > Create C file...** (Ctrl+F5) now offers "Current function and its callees recursively" next to "All functions" (or the selection). Callees are decompiled first, from the leaves up, so every function is decompiled after the functions it calls, and their recovered prototypes improve the pseudocode of their callers.

* calls through `.plt` and stub thunks are followed into the real function; imports are skipped; the root function is always included and only its callees are filtered
* the dialog offers "Skip debugger segments", "Skip library functions" (on by default: only the non-library functions of the current module are included) and "Decompile to cache only" (no file is written; reports how many functions were decompiled); the choices are remembered between sessions

### New Add-ons

#### IDA MCP Add-on

A first-party, open-source MCP server that connects your AI agents to IDA, fully locally and across multiple databases at once.

#### IDA Assist Add-on

Assist is an AI harness for reverse engineering, built into IDA. It works with any capable AI model, local or cloud, and combines the model with IDA's own analysis engines, emulation and an SMT solver to produce explainable results. It can analyze several databases at the same time.

#### Malware Analysis Add-on

A new Hex-Rays add-on for malware analysts: one-click unpacking, safe emulation of suspicious code, and sandbox results shown right in the disassembly.

***

## Higher-Level Language Support <a href="#hll" id="hll"></a>

### The Disassembler Recovers Swift Strings

The Swift compiler represents strings as two 64-bit immediates. A small string is embedded in the immediates themselves, a large literal is a tagged pointer, pointing at a fixed offset before its contents. This makes decoding Swift strings quite annoying, and typically required manual work, or writing a plugin. IDA 9.5 now has this logic built in, decodes the Swift strings, *and adds them to the String widget* (Shift-F12) for easier referencing. This mechanism is backed by our new Synthetic Strings API (see below) and is fully accessible to plugins. Here is an example of how the mechanism looks in real life (spot the decoded string at `0x220EA6B40`):

IDA 9.4:

```
0220EA6B30 MOV X8, #0x615373776F6C6C61
0220EA6B40 MOV X9, #0xEC000000203A6576
0220EA6B4C STP X8, X9, [SP,#0x80+var_78]
```

IDA 9.5:

```
0220EA6B30 MOV X8, #0x615373776F6C6C61
0220EA6B40 MOV X9, #isImmortal OR isASCII OR isSmall OR smallCount12 OR 0x203A6576 ; "allowsSave: "
0220EA6B4C STP X8, X9, [SP,#0x80+var_78]
```

### Loading of Go Binaries with Corrupt/Obfuscated Metadata

IDA now loads Go binaries whose metadata has been damaged or obfuscated:

* the pclntab is found even when its magic is overwritten, its section is stripped or renamed, or it is embedded inside another segment
* the Go version is recovered when no build string survives
* functions and names are recovered in garble-obfuscated binaries
* Go 1.27 binaries are supported

### Rust ABI on ARM\[64]/MIPS/PPC/RISC-V

`CM_CC_RUST`, introduced for x86 in 9.4, is now implemented for ARM64, 32-bit ARM, MIPS (o32 and n64), PowerPC (32- and 64-bit) and RISC-V (32- and 64-bit), so Rust binaries on those targets get their real arguments and return values instead of guessed ones. Alongside it:

* string literals appear in the pseudocode instead of a raw address, and the string-slice type is named `&str`
* panic and abort helpers are recognized as non-returning
* the exception handling tables of Rust binaries are parsed
* zero-sized members and parameters (the unit type `()` included) are dropped from DWARF-recovered Rust types, and the hidden environment pointer of a closure is recovered
* Rust binaries are detected without DWARF, even when stripped — by `rust_eh_personality`, the `rustc-` markers in read-only data, and legacy or v0 mangling — and their functions default to `__rust` instead of `__fastcall`
* with DWARF, each function's convention is checked by lowering its DWARF signature under the Rust ABI: functions mislabeled `__usercall`/`__fastcall` become `__rust`, and `extern "C"` helpers wrongly marked `__rust` are corrected. The argument locations in clang/LLVM Rust DWARF are corrected too (reversed big-endian register pieces, mis-rebased stack slots)
* a packed or under-aligned aggregate return no longer loses all but its first field (x86/x64 included); sub-word arguments promoted into full registers, and mixed arguments whose stack part comes before the register part, are handled
* compiler-generated wrapper types for array arguments and returns get descriptive names (`_20_arr_int`) instead of `retval_<ea>`, so identical types are shared

### Minor Improvements

* golang: string literals are recognized in the microcode, so they appear in the pseudocode instead of a raw address
* rust: panic and abort helpers are recognized as non-returning
* rust: more library functions that never return are recognized
* rust: the exception handling tables of Rust binaries are parsed
* rust: string literals are shown in the pseudocode instead of a raw address
* rust: the created string-slice type is named `&str`

### Bugfixes

* golang: negative `UnsafePoint` constants were shown as `0xFF` on unsigned-char targets
* golang: no type information was recovered from some big-endian binaries
* golang: no type information was recovered from some ppc64 binaries
* golang: an incomplete map type was recovered from Go 1.24 and later binaries
* rust: arm64: `u128` stack arguments were misaligned on macOS

## Decompiler <a href="#decompiler" id="decompiler"></a>

### Jump to Function Pointer Struct Members

The Enter key and a double click on a called function pointer member now go to the function that the member points to, and not to the declaration of the member. A member of this kind is one entry of a virtual function table, or one entry of a dispatch table that the program builds by hand. If the pseudocode names the object, IDA goes to the function of that object; if it does not, IDA offers the functions of all the objects that have the type. "Jump to structure definition" keeps its behavior, and a member that is not in a call keeps its behavior.

* the object can be a global, an array element with a constant index, a member of another structure or union, or a chain of these: `g_dev.ops.call()`, `g_tab[1].call()`
* when the object is not named, IDA scans every data item of the structure type: one target jumps directly, several open a "Possible callees of Type::member" chooser. Candidates come only from data items that have the structure type applied; for large arrays a cancellable wait box appears
* it works in the Dalvik class view as well

### "Split variable" for Register Variables

"Split variable" and "Unsplit variable" now work on register variables too, not only on stack variables.

The post-split occurrences are renamed to a fresh register before the use-def chains are built, so a separate variable starts at the split point. The split is validated first: the split point has to fully redefine the register, every renamed use has to be dominated by it, and a loop-carried self-referential accumulator is rejected. A function with no register split is unaffected.

### New "Create scattered pair" Operation

On 32-bit targets a 64-bit value can sit in a pair that no single storage location describes: reversed (low half in `r2`, high half in `r1`), non-adjacent (`r3`+`r12`), or a register plus a stack slot. Those used to be two 32-bit variables joined by `__PAIR64__` helpers, and retyping half of one to a 64-bit type simply failed. Pairs with evidence are now converted into one scattered variable automatically, and "Create scattered pair" / "Delete scattered pair" cover what the automatic recognition deliberately leaves alone. Scattered operands also propagate their names, so Go string variables in register pairs get their real names instead of `vNN`.

Shifts and multiplies of such a pair are fused into single 64-bit operations instead of separate `LODWORD`/`HIDWORD` updates.

* the command works on a `__PAIR__` expression or on any variable, with the other half picked from a list. The choice is saved with the function; "Delete scattered pair" also keeps the pair from being re-created automatically. When enlarging a variable fails, the warning suggests the command
* the automatic conversion needs evidence — the pair is compared, has a stack half, or occurs several times; x86 `edx:eax` pairs and 128-bit values are left alone. If the halves were named, the variable takes their name, minus a `_hi`/`_high` suffix

### Better x87 FPU Stack Handling

On x86, FPU stack recovery no longer gives up when a callee is typed as returning `void` or an integer but actually leaves a value on the x87 stack. The stack model is retried with such calls unpinned, the callee's return type is corrected, and a note names it at the call site — instead of the whole function dropping to inline `__asm`.

A function whose x87 stack model came out infeasible used to drop to inline assembly wholesale, and both common causes were callees with a wrong prototype, not the code being analyzed:

* a callee typed as returning an integer but returning in `st0` no longer pins the stack delta, so its callers decompile instead of dropping to `__asm`
* when the strict model fails, it is retried with such calls unpinned, instead of giving up with "inconsistent fpu stack"
* a prototype that cannot account for the values left on the stack gets a red header comment with the actual and the declared FPU slot counts, instead of a silent note in the Output window

### Merged Structure Fields Come Apart

A compiler initializes or compares several adjacent structure fields with one wide operation. Both are now undone when the members tile the accessed range exactly.

* each member's value is cut out of the constant in the program's byte order. Padding, a partially covered member, a union, or a base expression with side effects leaves the store alone
* `==` joins the parts with `&&`, `!=` with `||`. GUIDs benefit most: their fields show as recognizable hex constants instead of one large decimal number. Ordering comparisons are left alone
* the split is reversible per expression: "Unsplit expression" is offered on the generated assignments

### Swift Binaries Decompile Correctly Even When Stripped

The decompiler recovers the Swift calling convention and Swift error handling even when a binary carries no prototypes:

* the swift calling convention is recovered on stripped binaries: it is recorded at analysis time and applied at decompile time without being stored as a prototype, so call-site argument recovery keeps working. Arguments spilled to the stack at swiftcall sites are recovered as well
* throwing calls and functions are recovered on stripped binaries. At a throwing call the error result is surfaced as `__swift_get_error()`, so the following `if (error)` check reads normally instead of as opaque error-register traffic; a throwing function's own result type and `__swiftthrows` attribute are reconstructed
* runtime enum parameters are typed as enums instead of `void *`, and Swift is reported as the compiler in the output header

### Minor Improvements

* GCC/Clang builtin names (`__builtin_bswap32`, `__sync_fetch_and_add`, ...) are used for non-MSVC targets
* hexagon: variadic functions are recognized
* 64-bit variables stored in scattered register/stack pairs are recognized
* a bare constant stored into an unsigned variable is shown unsigned: a byte store of `0x9F` no longer prints as `-97`, and an HRESULT reads as `0x80070057` instead of `-2147024809`
* the carry flag of a constant left shift is folded into a bitmask test
* `x ^ ~x` is simplified to `-1` and `x & ~x` to `0`
* on 32-bit targets, 64-bit shifts and multiplies held in unaligned register pairs (such as `r1:r2` on ARM) are recovered as single 64-bit operations
* a carry flag used as a boolean value — a `bool` return value, for instance — is shown as a bitmask test such as `(x & 0x100) == 0` instead of `__CFSHR__`, and the carry of a left shift often simplifies further into a sign comparison
* hints for `sizeof()` and `offsetof()` show the numeric value
* a rotation that cannot move a set bit to the other end is shown as a shift instead of `__ROL__`/`__ROR__`: `__ROL4__((unsigned __int8)fe->PrologLen, 2)` becomes `4 * fe->PrologLen`
* a call returned directly by the function takes the function's return type, so a 16-byte result such as a Rust `&str` or a Swift `String` is no longer cut in half
* the function prototype editor ('y') no longer offers the argument names the decompiler invented (`a1`, `a2`, ...), so accepting the dialog does not turn them into real names
* arc: the arguments of MetaWare variadic functions are recovered
* arc: the vararg frame of MetaWare ARCtangent-A4 code built without helpers is recognized
* arc: the MetaWare compiler's millicode helpers are handled better
* v850: the 64-bit integer helpers of the GHS and CC-RH runtimes are decompiled instead of being left as calls
* ppc: cache, barrier, load-and-reserve/store-conditional, MSR/SPR/time base and FPSCR instructions are shown as intrinsics instead of `__asm` blocks
* more `memcpy` calls, also through pointers, are turned into plain copies, so more values propagate and dead code is removed
* x64: empty C++ records are dropped per the modern System V psABI; the legacy GCC < 8 layout is the new `-sysv_pre12` ABI option, set automatically from the DWARF producer

### Bugfixes

* vd: decompilation could fail with INTERR 52870
* vd: x87 instructions could be left as `__asm` statements when a function called from x87 code had a wrong integer return type
* vd: a bitfield access through a struct with an incomplete member could fail with INTERR 50689
* vd: variadic arguments were invented for `printf`-like wrappers called with a literal format string
* vd: setting a local variable or argument type could crash (INTERR 1098)
* vd: a stack argument could inherit the type of a local variable that reuses its slot
* vd: clicking a demangled name did not highlight the whole name
* vd: arm64\_32: decompiling code that takes the address of a stack variable could fail with an internal error
* vd: decompilation could fail with INTERR 52482
* vd: rust: a sub-word integer argument on the stack that the compiler loaded as a full slot was shown as `*(_QWORD *)(&arg - 1)`
* vd: early propagation of stack references ran before the control flow graph was built
* vd: a wrong member was used to access a small struct argument
* vd: a small struct or array passed in a wider register was accessed wrongly
* vd: a stack variable that used a guessed type could cause a crash
* vd: a wrongly defined `__m128` in the database could cause an internal error
* vd: float constants were printed imprecisely and without the `f` suffix, and were byte-swapped in big-endian databases
* vd: golang: assembly functions such as `runtime.memequal` decompiled as `void`, which could delete comparisons in their callers
* vd: a 256-bit AVX store to the stack failed to decompile
* vd: golang: a function with a stack argument failed to decompile
* vd: `-nosave` did not prevent saving the input database
* vd: x64: stack variables were not recognized in functions that align their frame pointer (AVX code)
* vd: auto-renaming offered register names such as `r3_0` as variable names, and could fail with INTERR 51365 on PowerPC
* vd: golang: write barriers (`runtime.gcWriteBarrier1..8`) took invented arguments, so every call site passed garbage
* vd: "Enable SSE intrinsics" and "Hide casts" could not be undone
* vd: x86: `bt reg, reg` kept a dependency on the upper bits of the index register, producing `LOBYTE()` and "possibly undefined" variables
* vd: arm64: values stored by prolog instructions (`STR Rt, [SP,#-N]!` in Rust code, for example) were lost
* vd: dalvik: decompiling nested calls with narrowed arguments could crash
* vd: ppc: an argument following a float argument got a wrong location
* vd: a guessed `__fastcall`-like calling convention could put the arguments of a call in the wrong places
* vd: mips: in MIPS16 functions with a frame pointer, stack accesses through `$s1` were shown as reads of an uninitialized register
* vd: setting a variable's type with "Setting type renames target" dropped or overwrote the name it already had
* vd: dalvik: corrupt try/catch data hung the decompiler and flooded the loader with warnings
* vd: v850: structure, union and bitfield accesses could fail with INTERR 51111, 51625 and 50698
* vd: reading the label of an empty nested block could crash
* vd: the pseudocode restored from the database was garbled for functions with try/catch (function roles were not serialized)
* vd: renaming a structure field accessed through a typedef had no effect
* vd: opaque Windows types such as `HWND` were not replaced by their typedefs
* vd: mips n64: references through the GOT were shown as meaningless address arithmetic, and calls through GOT slots were not resolved
* vd: a jump table of instructions was missed when its index was loaded from memory
* vd: pressing 'y' on the prototype line of the pseudocode did nothing
* vd: verbatim type names (Go's `[]string`, for example) were rejected by the "Set type" dialogs, and highlighted only partially in the pseudocode
* vd: dalvik: fields of a class that the file only references were shown as `__iget__`/`__iput__` intrinsics
* vd: changing a variable's type with automatic renaming enabled could crash
* vd: large functions could hang the decompiler (unbounded `get_bitwidth` recursion), and decompiling a switch with a huge value interval could run out of memory
* vd: swift: renaming a function parameter changed the wrong one, and a function returning a value wider than one register caused an internal error
* vd: ppc: restoring the TOC in PS3 ILP32 code could fail with INTERR 50836
* vd: ppc: AltiVec and byte-reversed loads in PS3 ILP32 code could fail with INTERR 50826/50920
* vd: ppc: string literals loaded through the TOC were not shown in the decompiler output
* vd: many other internal errors reported by users were fixed, across x86/x64, ARM, ARM64, PowerPC, MIPS and V850 code

## Disassembler <a href="#disassembler" id="disassembler"></a>

### Register Values Tracked Across Loops and Stack Variables

Firmware and C runtimes call arrays of function pointers in a loop — `__libc_init_array`, `.init_array`, `__libc_freeres`, driver tables:

```
s0 = address of an array of function pointers
loop:
  v0 = *s0        ; IDA wants to know where this call goes
  call v0
  s0 = s0 + 4
  goto loop
```

Those indirect calls had no cross-references, so whole subsystems stayed invisible. IDA now tracks a register that a loop changes by a constant step, and every function in the array gets a call xref; in a MIPS gzip uImage this uncovered 18 new functions.

* ARM and MIPS: a static array walked in a loop gets data and string xrefs to its elements; on ARM a structure array shows member offsets (`[Rn,#Struct.field]`), and `[Rn,Rm]` accesses and `ADD Rx, Rbase, #imm` on named data become offset expressions
* an array entry is accepted only if it points at code; the array ends at the first entry without a value, with a name or xref of its own, or that does not look like a function
* `REGTRACK_ALLOW_NUMLOOP` in `ida.cfg` switches it on per processor
* "Find a value" (Alt+Shift+V, formerly "Find register value") also resolves the stack variable under the cursor, and the return address pushed by `call $+5`
* SDK: a new loop value kind; plugins built against 9.3 see it as the old unknown-loop value

### ARC: Jump Table, Millicode Recognition and Other Fixes

* `bi`/`bih` jump tables are recovered as switches, and the ARCtangent-A4 indirect call idiom is recognized as a call
* the out-of-line millicode helpers of the MetaWare compiler are handled, and the arguments of MetaWare variadic functions are recovered
* `enter_s`/`leave_s`, the `bi`/`bih` switch jumps, multiplies, set-conditionals, divisions, `bmskn` and `min`/`max` are decompiled instead of being left as `__asm`. Functions that used to end in an asm statement and a `JUMPOUT` get real returns, and a `bi`/`bih` dispatch becomes a switch instead of always reaching case 0

Whole instruction families were never lifted, so they printed as `__asm`, and every use of their result read a pseudo-register. Every `leave_s` was a missing return.

With the products computed, the magic-multiply recognition runs and the divisions hiding behind those sequences come back. The flag-setting `.f` forms follow the "STATUS32 Flags Affected" table of the ARCv2 PRM:

```c
// 9.4
_R3 = g_timer_int_count;
__asm { mpyhu r3, 0xAAAAAAAB, r3 }
if ( _R3 >> 2 < dword_100007A0 )
__asm { mpy r0, r0, sizeof(gpio_info_t) }
v6 = (gpio_info_t *)((char *)gpio_ports_devs + _R0);
// 9.5
if ( g_timer_int_count / 6u < dword_100007A0 )
v6 = &gpio_ports_devs[dev_id];
```

Some instruction sequences used to decompile to wrong code: `bbit0 r13, r15, loc` used `r15` — its own second operand — as scratch and then zeroed it, so everything after the branch read 0 instead of the loop counter. The same defect was in `asr`/`lsr`/`asl`/`ror` and `btst`/`bset`/`bclr`/`bxor`/`bmsk`. The GCC millicode prolog/epilog helpers and the vararg home area are handled as well as the MetaWare ones.

### ARM: More Armv9 Extensions

The disassembler decodes FEAT\_LUT, FEAT\_CMPBR, FEAT\_CPA, FEAT\_LSUI, FEAT\_FPRCVT, FEAT\_MOPS, FEAT\_FCMA and FEAT\_SPECRES2. These are becoming mandatory in recent versions of the architecture.

### Hexagon: No-Return Analysis, Absolute Memory Target Handling, Switch-Case Discovery, Function Epilogues

Lots of improvements and bug fixes. Here are some highlights:

* GP-relative (small data) accesses are resolved against `_SDA_BASE_`, set with the new `QDSP6_SDA_BASE` keyword or in the processor options
* the ELF loader computes GOT and GOTREL relocations as the ABI specifies, handles the TLS relocations, and applies `R_HEX_32` to DWARF
* the epilog is found by the frame slot an instruction restores, not by its position, so predicated early returns are covered

```
// 9.4                                   // 9.5
r1:0 = memd(gp + #0xC8)                  r1:0 = memd(gp + #(.CONST_4040800000000000 - _SDA_BASE_))
r0 = memw(r17 + #-0x1A78)                r0 = memw(r17 + ##(listener_mut_ptr - _GLOBAL_OFFSET_TABLE_))
r0 = add(pc, ##loc_14@pcrel)             r0 = add(pc, ##.L.str@pcrel) // "Hello, World!\n"
memw(##0x4024C)                          memw(##g_a)
```

### Support for MIPS R6 Instructions

IDA now fully supports MIPS Release 6 in both the disassembler and the decompiler:

* all R6 integer and FPU instructions are decoded, including those introduced with new encodings in R6
* compact branches and jumps are supported
* the decompiler handles R6 branches, jumps, selects and FP comparisons
* R6 can be selected for plain (headerless) binaries, and PLT stubs are named

### Game Consoles: PlayStation 3, Xbox 360, Wii U and PlayStation Portable

* PlayStation 3: the disassembler and decompiler support 64-bit PowerPC with 32-bit pointers (celloslv2 ILP32). PS3 executables load with ILP32 segments and correct TLS variable addresses.
* Xbox 360 and Green Hills (Wii U): the out-of-line register save/restore helpers (`__savegprlr_N`/`__restgprlr_N`, `__savefpr_N`/`__restfpr_N`, `__savevmx_N`/`__restvmx_N`) are now named. The decompiler treats them, and their PS3 counterparts, as prolog/epilog. Callers decompile with correct arguments and return values, and without spurious calls. You no longer need to type the helpers as `void __spoils<>()` by hand.
* Xbox 360: stubs that use `r12` as the link register or save vector registers are handled too. For example, `JUMPOUT(0x80078B0C);` now decompiles to `return v6;`.
* Xbox 360: `.pdata` entries are decoded with their own layout, not as a Windows CE variant. Hand-written stubs with the 32-bit flag clear no longer have their length halved.
* PlayStation Portable (Allegrex): a new `single_float` ABI option, on by default, passes floats in consecutive FP registers and doubles in GPRs. The decompiler uses the same ABI to reconstruct prototypes, so float and double arguments are deduced correctly.
* PlayStation Portable: the ELF loader supports packed PRX relocations.
* AltiVec/VMX128 Intrinsics: on PPC, AltiVec/VMX128 vector instructions are shown as intrinsics named after the Xbox 360 XDK ones (`__lvx()`, `__vaddfp()`, ...), with real vector variables as arguments and results.

### WebAssembly Loader and Disassembler

IDA loads and disassembles WebAssembly modules, up to and including WebAssembly 3.0, such as those built by Emscripten, Rust or Kotlin/Wasm.

* the whole instruction set: SIMD including relaxed SIMD, atomics, bulk memory, reference types and typed function references, garbage collection (structs, arrays, recursive type groups, subtypes, casts, `i31`), exceptions (`try_table` and the legacy `try`/`catch`), tail calls and multi-value blocks
* 64-bit memories and tables, multiple memories, extended constant expressions and the element-expression encoding
* stack code is folded into readable operands: `local.get A; local.get B; i32.add` reads as `i32.add A, B`
* names come from the module: functions, locals and globals, and also types, fields, tags, tables and data and element segments
* signatures become function prototypes, GC structs and arrays become local types, and globals get their declared types
* every linear memory becomes its own segment, and a constant address in a load or store becomes a data cross-reference
* blocks are indented by nesting, the block around the cursor is highlighted (processor option `WASM_MATCH_BLOCKS`, on by default), and branches, catch clauses and handlers have code cross-references to their targets
* the name, linking, dylink.0, producers and source-map custom sections are parsed and annotated

### Bugfixes

* mips: allegrex: malformed VFPU instructions could crash IDA while decoding
* ppc: in binaries with several TOCs, the TOC value was not resolved for functions without an `.opd` entry

## Analysis & Kernel <a href="#analysis" id="analysis"></a>

### Exception Handling: Correct Stack Levels and Robust Try Blocks

A landing pad is entered by the unwinder, not by the code in front of it — yet IDA took its stack pointer level from the preceding instruction, and every stack variable after it was off.

* a landing pad now takes the stack level of the region it guards. The fix is in the kernel, so it covers every processor module that lets the kernel compute block levels: ARM, MIPS, PPC, RISC-V, SH4, Hexagon, NDS32 and TriCore
* x86: the landing pads of gcc-built PE files (MinGW, Cygwin) get the levels of their guarded region, as ELF files already did; the handler and filter funclets of a Windows `__try` are no longer fed to the SP model, since the OS calls them with frames of their own; and the stack cleanup after a call to a non-returning function, or in a handler of a region that does not end the block, gets the right delta
* one malformed try block no longer discards all the others in the same range (a function with 7 good blocks and 1 bad one returned none), and a block reaching past the end of the program no longer hides the later ones
* the guarded region of a C++ `try` block is part of the function even when it ends with a call that never returns, and the landing pad of an empty exception specification is no longer lost
* x64 epilogs restoring registers from `[rsp]` without a displacement are recognized
* files with a huge exception handling table analyze much faster, and files without SEH handlers skip the search for their owners

### Minor Improvements

* analysis: the new `OVERSIZED_FUNC_SIZE` option in `ida.cfg` (default 0, off) flags larger functions as oversized (`func_t::is_oversized()`) and records a problem; on x86/x64 their stack-frame, SP, switch-table and stack-variable analysis is skipped. This protects against binaries built with huge functions to slow IDA down
* analysis: the new `JUMPTABLE_MAX_INSNS` option in `ida.cfg` bounds the work of a single switch pattern match, so obfuscated code cannot make one switch stall the analysis

### Bugfixes

* analysis: struct-typed stack variables named `~rN` were shown as `byte`
* types: a structure whose first member is empty, passed in registers as gcc does, could cause INTERR 10147
* analysis: a prototype guessed from a demangled name could discard a good one
* analysis: 128-bit values were shifted right incorrectly by 64 bits or more
* arm64: Windows computed 128-bit products and quotients incorrectly
* types: a gcc enum whose values need 64 bits got a 16-byte type
* analysis: "autoanalysis finished" was not the last message
* analysis: a type guessed from the symbol name was preferred over a type library prototype
* analysis: the initial autoanalysis could take hours on a file with a huge array
* database: closing a database could end with internal error 840
* names: a function reached through a named thunk was given a suffixed duplicate of the thunk's name
* names: names starting with a dummy name prefix could crash IDA
* sdk: `DBFL_COMP` was ignored by `save_database()`
* names: forced renames could corrupt names supplied in the database encoding
* sdk: `fpvalue_t::to_float`/`to_double` returned byte-swapped values on big-endian databases

## UEFI <a href="#uefi" id="uefi"></a>

IDA 9.5 ships with a new UEFI plugin and loader. We still plan to refine this plugin in next beta versions and releases. The main focus was on the DXE environment for this release.

An entire UEFI firmware image (SPI flash dump, capsule body or firmware volume) can be loaded into one database. The new UEFI plugin analyzes UEFI modules, both single EFI/TE files and every module of a firmware image. It runs automatically after auto-analysis and adds names and types, allowing known protocols calls to decompile to readable code:

```
gBS->LocateProtocol(&gEfiPcdProtocolGuid, NULL, (void **)&gEfiPcdProtocol);
gEfiPcdProtocol->GetBool(1068);
```

* Entry points are named after their module and typed by FFS file type. In a firmware image, functions are grouped into folders by module.
* Globals pointing to service tables: `gBS`, `gRT`, `gST`, `gSmst` and `gImageHandle` are automatically found and typed.
* Protocols: installs, locates and notifications are found. GUIDs, interface pointers and implementations are typed and named, e.g. `DiskIoDxe_EfiDriverBindingProtocol_Start`. Currently vendor protocols that no type library describes get a synthesized structure, but this behavior might still change.
* A new "UEFI protocols" window (View > Open subviews) lists every install, uninstall, locate and notify, with filters by kind and by module type (accessible via right click).
* Cross-references are added from protocol member calls to their implementations, across modules. Double-clicking `x->Member` in the pseudocode jumps to the implementation, and a popup action lists a member's call sites. This works when a structure for the protocol is available.
* Read-only strings in `.data` are shown inline, and `DebugPrint`/`DebugAssert` calls are recognized.
* Options are in `cfg/uefi.cfg`.

### Minor Improvements

* dex: DEX items are shown decoded instead of as stored comments
* dex: DEX version 040 files are supported
* dex: all try blocks are kept for methods with more than 127 of them
* dex: VDEX files are supported
* elf: arc: `R_ARC_H30` relocations are supported
* loader: zstd-compressed input files are decompressed transparently
* macho: the kernelcache and dyld cache headers are shown expanded
* macho: load commands are typed from the type libraries, and path fields link to their strings
* macho: the `vmaddr` of `LC_FILESET_ENTRY` is shown as an offset to the KEXT's header
* macho: `arm64e.x1` files are recognized and labeled
* macho: the Functions list has a folder per KEXT or cache image

### Bugfixes

* elf: mips: `R_MIPS_PC32` relocations were not applied
* elf: mips: calls to external functions were not resolved in MIPS n64 object files
* elf: mips: when several HI16 relocations were paired with a single LO16 (a GNU extension), only the last HI16 of the series was applied
* elf: mips: PSP relocations exposed both as sections and as a program header were applied twice
* dex: malformed uleb128/annotation offsets could cause INTERR 2765 during loading
* dex: a malformed DEX file could crash IDA while loading
* dsc: when the indirect symbol table was stripped, `__auth_stub` entries were not named after their own callees
* macho: a corrupted bind opcode created a bogus import
* macho: cross-references for tagged pointers in files with chained fixups were wrong

## Type System <a href="#typesystem" id="typesystem"></a>

### Clang Is the New Default Parser

IDA 9.5 parses type declarations with a built-in clang-based parser: C, C++, Objective-C and Objective-C++ declarations work out of the box, with no setup required. The legacy parser remains available in the "Compiler options" dialog. The default is `TYPE_PARSER = "clang"` in `ida.cfg`; `"legacy"` still works. Loaders also use the selected parser for the prototypes they create (the ELF loader's `__libc_start_main`, the `__cxa_*` helpers of exception handling, guessed function-pointer types). The type editor and Local Types have a language selector (C, C++, Objective-C, Objective-C++), saved per database.

**Removed:** The `old_clang` parser, the idaclang plugin and the standalone `idaclang` tool, deprecated in 9.4, are removed. `tilib -TC` is the tool for building type libraries; the documentation has an idaclang → tilib command map.

### Version-Matched XNU Type Libraries for Apple Silicon macOS Kernels

When loading an Apple Silicon macOS kernel, IDA now automatically applies the XNU type library that matches the kernel's OS version, so kernel structures and function prototypes are typed correctly out of the box.

### Minor Improvements

* types: structures can declare the order their bitfields are allocated in
* clang: the deprecated `old_clang` parser and the standalone `idaclang` tool have been removed; use the built-in clang parser and `tilib -TC` instead

### Bugfixes

* clang: a bad declaration was not reported to the user
* clang: some declarations that the legacy parser accepted, such as a non-standard prototype for `main`, were rejected
* clang: headers emitted by IDA with anonymous types could not be parsed back
* clang: demangled data declarations of const objects were rejected
* clang: names known to the type library or the compiler were not resolved
* clang: types guessed from demangled MSVC names were wrong
* clang: structure packing passed in flags was ignored
* clang: prototypes without a calling convention did not keep the platform default calling convention
* clang: on targets where `int` is not 32-bit (e.g. 16-bit DOS), `__int32` and the other `__intN` types followed the width of `int`
* clang: a declaration with an unresolvable `decltype()` crashed IDA

## Debug Info, Demangling and Exception Handling <a href="#debuginfo" id="debuginfo"></a>

### Minor Improvements

* demangler: swift: names produced by Swift 6 compilers are demangled
* dwarf: zero-sized Rust parameters are dropped
* dwarf: the Rust unit type `()` is represented as a zero-size struct in aggregates
* dwarf: zero-sized members are dropped from Rust structs and unions
* dwarf: `DW_AT_noreturn` on subprograms is honored
* dwarf: Objective-C/Swift runtime root classes are represented with their isa pointer
* pdb: the bitfield allocation order is recovered from the debug information
* goodname: new patterns for MSVS STL names

### Bugfixes

* demangler: cv/reference qualifiers on a substituted template-id were misplaced
* demangler: names with braced initializer lists in template arguments were not demangled
* demangler: some local C++ names were not demangled
* dwarf: `DW_AT_type` and names were not applied to globals (and function-local statics) whose location used `DW_OP_addrx`
* dwarf: function arguments spilled to SP-relative slots were not named and typed
* dwarf: incomplete C++ types were dropped to `void` instead of being recovered
* dwarf: PowerPC floating-point arguments were mapped to the wrong registers
* dwarf: the hidden environment pointer of Rust closures was not recovered
* dwarf: C++ base subobjects smaller than `sizeof(base)` were rejected
* pdb: the "Load types" option was ignored (type processing was not skipped when it was off)
* pdb: function prototypes were not applied for COFF objects with embedded `/Z7` debug info
* pdb: some MSVC COFF objects compiled with `/Z7` got wrong argument types
* pdb: struct and array data globals were not laid out from debug info
* swift: functions were no longer grouped by module in a shared cache

## UI & UX <a href="#uiux" id="uiux"></a>

### From Qt 6.8 LTS to Qt 6.12 LTS

Qt 6.12 is the next long-term-supported Qt.

* IDA follows the desktop's light/dark scheme (on Linux through the XDG desktop portal); `IDA_COLOR_SCHEME=light|dark|auto` forces one
* the dedicated Copy/Undo/Back/Exit keys some keyboards have are registered as shortcuts, and the shortcut editor, cheat sheet and command palette list them
* PySide6 is upgraded along with Qt: retest plugins that use PySide

### New HTML Renderer for Listings

Every listing — disassembly, hex, pseudocode, type listing — can be copied and exported faithfully, colors included. The context menu's new **Copy** submenu copies the selection, the highlighted identifier, or the current function/type/item **as text** (Ctrl+C), **as HTML** (pastes styled), or **as a deeplink**; type listings also offer **Copy with dependencies**.

**File > Produce file > Export to HTML...** replaces the old HTML output with a template-driven export: a plain static page, an interactive page with a function sidebar, jump arrows and cross-reference links, or a paste-ready snippet — and custom templates are plain IDAPython scripts. The engine behind it (`export_listing`) is available to plugins, IDAPython, and idalib.

* **Copy > As HTML** inlines the syntax colors, so the snippet pastes styled into any HTML-aware editor or chat; Copy honors an intra-line or column selection and falls back to the highlighted item
* three templates ship — Document (a standalone page), Interactive (function/type sidebar, jump arrows, working cross-reference links) and Snippet — in `python/examples/templates/`; a `.py` file dropped next to them is picked up by the dialog
* exported HTML has working links for names, cross-references and pseudocode call targets
* export works on the selection, the current function or type, or the whole database, and can open the result in the browser
* `export_listing` runs in the kernel, so idalib scripts and agents use it without a UI; an idalib example ships

**Migration:** the decompiler's own "Generate HTML" action is retired in favor of the generic export; `gen_file(GENFLG_GENHTML)` stays. Plain "Copy" is now "Copy > As text" and keeps Ctrl+C.

### Pathfinder and Xref Graph Are Strongly Linked and Improved

The Pathfinder answers questions such as "how does this malware get from `WinMain` to `connect()`?". In 9.4 it was a list without visual feedback; in 9.5, opening it opens a live xref graph beside it, and adding, removing or reordering waypoints, or changing exclusions, redraws the graph at once.

* between two waypoints the list shows a segment: "Direct connection", "N nodes", or "N nodes (shortest: M)" — in red when there is no path. Expanded, it lists the nodes by distance, syntax-colored; a segment can be folded to its shortest path, with the other nodes greyed out
* "Promote to waypoint", "Exclude from path" and "Show in graph again" work in the list and in the graph; deleting a node in the graph only hides it. If two waypoints only connect in reverse, IDA swaps them and says so; nodes grown by hand stay part of the path
* paths are saved in the database once they have a waypoint, named after their ends, listed in the Xref Graph manager and recomputed on open. The Pathfinding submenu — Create new path (Shift+F9), Add to latest path (Ctrl+Shift+F9), Add to — works in every window that shows addresses
* a path larger than the graph's node threshold asks whether to draw it all or only each segment's shortest path

The xref graph itself routes edges orthogonally (and keeps them orthogonal while you drag a node), has rounded corners, shows the contents of string literals in their nodes, counts nodes and selected nodes in its bottom bar, and Ctrl+Up/Down jumps between connected nodes.

**Migration:** the Tree/Graph buttons became context-menu actions, and "Open Pathfinder" gave its shortcut to "Create new path".

### Reworked Quick Filter Mechanism

* typing in a list or chooser window (Functions, Names, Imports, Local Types, ...) filters it, instead of running an incremental type-ahead search. Only keys that no shortcut claims reach the filter, and `Alt+T`/`Ctrl+T` still search without filtering
* the quick filter bar is a permanent part of those windows, so it is always clear where what you type is going, and the list no longer reflows on the first keystroke
* both are feature flags under **Options > Feature Flags**: untick "Typing in a list filters it" for the incremental search, digits jumping to a row by number and `Ctrl+Enter`/`Ctrl+Shift+Enter` stepping between matches included; untick "Always show the filter bar" to open the bar on demand, with a close button
* typing a character that needs AltGr, as Polish, Croatian and Vietnamese layouts do, reaches the filter; so do the numpad digits

The incremental search was hard to discover, and because it never timed out, a forgotten search kept swallowing single-letter shortcuts. In 9.5, shortcuts always win over typing, still toggles check boxes, and Down/Esc in the filter return to the list.

**Deprecation:** both feature flags are temporary. Unless there are objections during 9.5, the incremental search and both flags are removed in 9.6.

### Jump Anywhere Shows More and Finds More

* results are syntax-colored, and function results show their parameter names (types are left out to keep rows short; unnamed parameters show as `arg1`, `arg2`, ...). "Show function signatures" in the gear menu turns this off
* the preview pane is always on; the feature flag that disabled it is gone, so a user who had turned it off gets it back
* the scrollbar spans the whole result set instead of growing while you scroll
* a local type is found by its prettified name as well as by its raw one
* module symbols are no longer missed while debugging, and after a compaction a result no longer points at the wrong local type

### Minor Improvements

* the widget numbers for Alt+ window switching appear after 500 ms instead of 1 s
* demangled names are displayed by default
* "deep select" for grouped names: Alt-click a qualified name to highlight only the component under the cursor
* qualified names are highlighted as a whole
* double-click jumps to a type's definition (in prototypes) or to a struct member (in operands)
* pressing in a chooser embedded in a form no longer closes the enclosing dialog
* Shift+Enter in choosers and tree views jumps to the item without moving the keyboard focus
* the type editor reads a declaration as C, C++, Objective-C or Objective-C++
* the type editor has a new "Declaration" tab, and the Compiler options dialog is more compact
* Ctrl+drag selects whole lines
* the raw name behind a prettified one is painted translucent
* hovering a prettified type name shows its full name
* the Types window shows and filters on the prettified type name
* dsc: kc: the DSC Index and KC Index trees are sorted alphabetically
* teams: the status bar panel names the workspace and details it in its tooltip
* teams: its status is reported in a single status bar panel
* "Export data" moved from the Edit menu to **File > Produce file**
* a new "Extensions" menu gathers Lumina, Teams and the other Hex-Rays extensions; the Lumina and Teams top-level menus are gone, but plugins attaching actions to "Lumina/..." or "Teams/..." menu paths keep working
* a newly loaded file opens on the monitor where the main window is, instead of always on the primary monitor
* pathfinder: paths are saved and listed in the "Pathfinding" submenu
* pathfinder: dead-end pairs are swapped automatically, and the hovered segment is highlighted
* pathfinder: new "Promote to waypoint" action, and one popup menu for all three views
* pathfinder: nodes grown by hand stay in the path
* pathfinder: waypoints are shown as a tree of each segment's nodes
* pathfinder: path actions work in every window that has addresses
* pathfinder: a path segment can be folded to its shortest path
* xref graph: Ctrl+Up/Down jumps between connected nodes
* xref graph: the bottom bar shows node and selection counts
* xref graph: zooming has a keyboard shortcut
* xref graph: the contents of string literals are rendered in nodes
* xref graph: edges are routed orthogonally in the layout
* xref graph: the edges of a dragged node stay orthogonal
* xref graph: nodes and edge bends have rounded corners

### Bugfixes

* teams: the file trees triggered INTERR 80130 after pulling a file from the vault
* teams: opening the "Vault files" widget triggered INTERR 72549
* macos: the widget numbers used for Alt+ window switching appeared while holding Cmd instead of Option
* the "Load a new file" dialog did not highlight the chosen processor in bold
* the "Analysis" toolbar indicator did not turn green when analysis was idle
* in the Local Types view, clicking a qualified type name did not highlight the whole name
* pressing Enter did not accept a form when focus was on a checkbox or radio button
* opening the navigation drop-down of a view that shares its history with a different kind of view crashed IDA
* pressing in a tree view's quick filter did nothing
* middle-clicking a tab closed two views instead of one
* a chooser's "Line N of M" counter went blank in folders-only mode
* changing the demangled names settings did not update the windows right away
* the "bottom line padding" setting had no effect
* typing a character that needs AltGr in a list (as Polish, Croatian and Vietnamese layouts do) did nothing
* the wrong segment attribute was used to calculate the segment base
* the release notes were shown again on every start when switching between two IDA versions
* disabled check boxes and radio buttons looked enabled in the dark theme
* the Pathfinder and the Scripts window had no Alt+N number
* a mouse selection cleared the clipboard on Wayland
* tree views such as Bookmarks and Breakpoints showed "Edit function"/"Delete function" in their popup menu after the Functions window had been used
* the prototype editor's validity indicator checked stale text
* pressing in a dialog discarded the changes when a checkbox had the focus
* "Copy full type" was unavailable on function types in Local Types
* pathfinder: the selected waypoint row was unreadable in light mode
* pathfinder: a node could be a waypoint and an exclusion at once
* a backward search did not walk the occurrences in order
* an identifier search did not find the next occurrence
* a type whose member references a non-C type name could not be edited in C syntax in the type editor
* copying several rows of the xref tree did not keep the tree order
* xref graph: the headers and icons of rendered nodes overlapped each other
* xref graph: node icons activated on press instead of on click

## FLIRT & FLAIR <a href="#flirt" id="flirt"></a>

### Minor Improvements

* flirt: a pattern can be created from a selected byte range
* flair: pelf: ARC ELF files are supported
* flirt: signatures can carry original (unmangled) symbol names
* flirt: narrow/wide MSVC runtime twins (main/wmain, WinMain/wWinMain, argv accessors, environment helpers) are named from evidence in the binary
* flirt: the ARM and ARM64 MSVC runtime signatures are regenerated and cover VC11 through VC 14.52
* flirt: the 64-bit MSVC runtime signatures are picked by the CRT linkage of the binary
* flirt: the functions and data that the entry module of a startup signature references are named
* flirt: a startup signature is accepted even when its references are not resolved yet
* flirt: the names of the narrow/wide startup globals are kept
* flirt: 32-bit MSVC binaries of VC 14.39–14.52 are recognized, and their runtime is picked by the CRT linkage
* flirt: arc: a new signature covers the millicode helpers

### Bugfixes

* flirt: a 32-bit wWinMain program lost the name of its entry point
* flirt: a startup signature applied as an ordinary one named its entry module after the directive string

## Performance & Resource Consumption <a href="#performance" id="performance"></a>

### Large Binaries: Less Memory, Fewer Stalls

* **DWARF at scale:** debug sections are memory-mapped instead of read into memory, which saves about 2 GB (−30%) on a 2.6 GB C++ binary, and the per-DIE index on an 89.5-million-DIE binary shrinks from 2048 MB to 1109 MB. The new opt-in `-Odwarf:lazy_types=1` imports only the types reachable from named functions and globals, so huge C++ binaries that used to run out of memory load
* **dyld shared caches:** enabling an address range no longer rewrites the whole database. On a 2.7 GB cache, initial load and analysis freeze the UI for 8.1 s in total instead of 42–48 s (worst single freeze 5.4 s instead of 13.5–15.9 s; UI-thread I/O 21 GB instead of 234 GB). Building the cache's region map takes 1 s instead of 5 s
* **pathological inputs:** the data copied by RTTI analysis of a file with 800 classes and 200k strings drops from 37.1 GB to 36 MB; auto-analysis of huge functions with flattened control flow (a dispatcher on a state register) drops from 1751 s to 253 s; creating names in a reopened database no longer slows down as the database fills; binaries built to slow IDA down can be reined in with `OVERSIZED_FUNC_SIZE` and `JUMPTABLE_MAX_INSNS` (see Analysis & Kernel)
* **decompiler:** batch decompilation no longer slows down quadratically (8% faster on 26k functions, 11.8% on 74k); decompiling a function with one 5506-instruction basic block drops from 2929 s to 148 s
* **FLIRT:** signature files are read through a buffer instead of a byte at a time
* **start-up:** parallel IDA instances no longer keep rebuilding the processor module cache, and a run without IDAPython no longer forces the next run to reload every processor module (running the shipped Python processor modules costs about 200M instructions)
* **databases:** "collect garbage" reclaims the space of deleted address ranges, and the prototype editor no longer grows the database with every use

### Minor Improvements

* database: databases can be packed as several independent zstd frames (`PACK_ZSTD_FRAME_SIZE` in `ida.cfg`, in MB, default 32), so tools such as IDA Teams can decode them in parallel: checking out a 9 GB database went from 2.3 s to 0.3 s
* dsc: the region map of a dyld shared cache is built in linear time
* dwarf: memory usage is lower when loading binaries with a huge number of DIEs
* dwarf: debug sections are memory-mapped, which reduces memory usage
* dwarf: the per-DIE memory overhead is lower when loading binaries with many DIEs
* dwarf: new opt-in on-demand type loading for very large binaries
* rtti: analysis is faster; it used to slow down disproportionately on files with many C++ classes
* types: adding many names to a type library is faster
* tilib: parsing an enum with many members is faster
* names: creating names in a reopened database no longer gets slower the more names the database already contains
* parallel IDA instances no longer keep rebuilding the processor module cache
* a run of IDA without IDAPython no longer makes the next run reload every processor module
* regfinder: auto-analysis of huge functions with flattened control flow is much faster
* database: enabling an address range no longer rewrites the whole database
* names: name printing in `apply_regexes`/`qregsubst` is faster
* database: "collect garbage" also reclaims the space of deleted address ranges
* database: the function prototype editor no longer saves its cursor positions in the database, which grew it with every use
* flirt: signature files are read through a buffer instead of a byte at a time
* vd: building chains is faster (the block of a chain bit is checked in constant time)
* vd: rule CMB7 looks back at most 128 instructions for its `mov 0`, which bounds its cost
* vd: builtin patterns are rejected on the first block before a match is built, which saves time
* vd: leak checking counts live ctree items instead of copying their set, which saves time and memory
* vd: each expression type is checked for printability only once per decompilation
* vd: functions with long basic blocks decompile much faster: a function with one 5506-instruction basic block went from 2929 s to 148 s
* vd: batch decompilation no longer slows down quadratically with the number of decompiled functions
* swift: the Swift identifier characters are set once per database instead of repeatedly
* analysis: the frame members a stack variable overlaps are looked up instead of all being copied
* pathfinder: expanding a large path segment no longer takes seconds
* xref graph: large graphs are much faster to open, grow and rebuild

## Configuration, IDAPython, SDK & API <a href="#sdk" id="sdk"></a>

### Installation Manifests for Loaders, Processor Modules, Type Libraries, FLIRT Signatures, IDS Files and Themes

Loaders, processor modules, type libraries, FLIRT signatures, IDS files and themes can now be installed the way plugins are, as a directory that holds a manifest file. The manifest has the same shape as `ida-plugin.json`:

```json
{
  "IDAMetadataDescriptorVersion": 1,
  "loader": {
    "name": "my loader",
    "entryPoint": "my_ldr.py"
  }
}
```

* the manifest names are `ida-loader.json` (`loaders/`), `ida-proc.json` (`procs/`), `ida-til.json` (`til/`), `ida-sig.json` (`sig/`), `ida-ids.json` (`ids/`) and `ida-theme.json` (`themes/`); loaders and processor modules need an `entryPoint`, the other kinds do not
* a type library or signature directory can carry files for several processors: IDA searches `<dir>/pc/`, `<dir>/arm/` and so on, the same as in `til/` and `sig/`. A type library can also be in `<dir>/` itself; a signature must be in the processor subdirectory
* an extension pack bundles several kinds in one directory. Put an `ida-extension.json` manifest in `$IDAUSR/extensions/<pack>/`, and the extension directories in its `loaders/`, `procs/`, `til/`, `sig/`, `ids/`, `themes/` and `plugins/` subdirectories. IDA ignores other files in these subdirectories
* packaged type libraries and signatures appear in the "Available type libraries" and "Available signatures" lists, and packaged themes in the theme selector
* IDA searches in this order: `$IDAUSR/<kind>/`, the packs in `$IDAUSR/extensions/`, the directory in `IDATIL`, `IDASGN` or `IDAIDS`, `$IDADIR/<kind>/`, and the packs in `$IDADIR/extensions/`. In each directory, files installed the classic way come first, then the extension directories sorted by name. If two plugins, loaders or processor modules have the same name, IDA uses the first one. Names that differ only in case are the same name
* a plugin, loader or processor module directory gives IDA only its entry point. The other files in the directory, for example helper scripts, do not hide files that IDA searches for by name
* IDA looks for extensions one time per session. Restart IDA after you install an extension
* loaders, processor modules, type libraries, signatures, IDS files and themes can be installed as directories with an `ida-<kind>.json` manifest, like plugins

### New "Synthetic String" API

A plugin can now add strings that exist only in the code.

### New "License Inspection" API

The new `License` class (`license.hpp`; `ida_license.License` in IDAPython) lets a plugin query the active license (whether it is usable, its product and edition, its activation period, and the add-ons and features it covers) and control it (set the active license, check a license out and in, borrow and return a floating license); see the `licinfo` sample plugin and the `print_license_info.py` example.

### `COLOR_GROUP` is now `COLOR_SEMSPAN`

`COLOR_GROUP` is renamed `COLOR_SEMSPAN` ("semantics-bearing span"), which says what the tag is actually for: it groups a run of tagged text into a single unit — that is how a qualified name highlights as a whole — and carries semantics about it: a one-byte kind, plus an opaque payload of *variable size* that Hex-Rays reserves the right to grow in any release. Never assume a size for that header: step over it with `tag_skipcode()`/`tag_skipcodes()`/`tag_advance()`, and read it with `tag_get_semspan_kind()`. `COLOR_GROUP` stays as a deprecated alias; the accompanying `tag_semspan()`, `tag_semspan_off()`, `PRTYPE_SEMSPAN` and `GNCN_SEMSPAN` are new in 9.5.

### Minor Changes

* dsc: `DSCU_USE_SEG_PREFIXES` (`dscu.cfg`) is honored for cache-image segment names
* macho: `USE_SEG_PREFIXES` is retired in favor of the more versatile `SEGNAME_FORMAT`, harmonized across kernelcaches, dyld shared caches and plain Mach-O; the old option is still honored for backwards compatibility
* hexagon: new `QDSP6_VALIDATE_DUPLEX` option
* hexagon: processor options can be set in `ida.cfg`
* the maximum stack frame size is configurable
* decompiler: `set_decompiler_timeout(msecs)` bounds a whole `decompile()` call (internal retries included) and fails with the new `MERR_TIMEOUT`; intended for headless and idalib runs, where there is no Cancel button
* decompiler: added save/restore APIs for split settings and for vararg call arguments
* the length of string literal comments is configurable (`STRLIT_COMMENT_LENGTH`)
* `ev_sanitize_name` receives the kind of name being sanitized
* clang: the clang type parser is the default and is also used while loading
* new listing-export API (`export_listing`): renders disassembly, pseudocode and type listings as text or HTML; available to plugins, IDAPython and idalib
* decompiler: new class API. `get_classes()`, `get_class_info()`, `render_class()` and `render_member()` give a language-neutral view of the program's classes, their members, and the class view's rendering of them; available to C++ plugins and IDAPython (see the `list_classes.py` example)
* new `qgetpid()` returns the id of the current process
* try block structures can be compared with `==` and `!=`
* idalib: an old `.idb` opened with idalib is converted to `.i64` automatically, and the session continues on the converted database
* sdk: `qvector` has a new `append(first, last)` to append an element range

### Bugfixes

* sdk: `qtree.hpp` could not be compiled with GCC 8.x
* sdk: `qustrncpy()` cut a 4-byte UTF-8 character that fit in the buffer
* idapython: objects a script created, such as hooks, stayed alive after the script ended
* idapython: raising `SystemExit` from the CLI closed IDA
* idapython: `ask_file` with empty string arguments crashed IDA
* idalib: a failed `open_database` terminated the host process
* plugins: when two plugins in subdirectories of `plugins/` had the same name, the order of the files on disk selected the plugin that IDA loaded
* idapython: a processor module script could not import a Python module installed next to it

## Network & Security <a href="#network" id="network"></a>

### Clear Answers When a License, Lumina or Vault Server Misbehaves

* a failed connection names the server (`host:port`) and leads with the cause instead of a bare transport error, and a missing license is reported as "license X is not available on this server". The License Manager and the `lsadm`, `hv` and `lc` tools share the same classification
* IDA no longer freezes when the license or Lumina server stops responding — during work, on exit, or during cloud decompilation: blocking network operations are bounded or can be cancelled
* macOS: IDA uses the TLS-1.3-capable LibreSSL the system ships, so it connects to servers that require TLS 1.3 and to FIPS servers that require the Extended Master Secret extension (the handshake used to fail with alert 80)

### Minor Improvements

* security: Linux builds are hardened with full RELRO and PLT-free linkage, making them more resistant to memory-corruption exploits

{% hint style="info" %}
**Share your feedback**

Spotted a bug or have a suggestion for the beta? Let us know and contribute to IDA evolution through one of the following channels:

* [Hex-Rays Support](https://support.hex-rays.com) (*Early access* feedback form),
* Email: <support@hex-rays.com>, or
* Slack: Join the discussion in our dedicated beta channel. If you didn’t receive the invitation link, [contact us](mailto:support@hex-rays.com).
  {% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hex-rays.com/release-notes/9_5beta.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
