> 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/ida-9.5/core/decompiler/concepts/bitfield-accesses.md).

# Bitfield member accesses

{% hint style="info" %}
This page is about members of a C structure declared like `unsigned int kind : 3;` and not a [bitfield enum](/ida-9.5/core/disassembler/concepts/bitfields.md), which is a bitmask type applied to an instruction operand.
{% endhint %}

When accessing C bitfields, the compiler works on the storage unit that holds the field and extracts the bits with a mask and a shift. Take this structure, where `kind` occupies bits 3 to 5 of a 4-byte unit:

```
struct state
{
  unsigned int ready : 1;
  unsigned int busy  : 1;
  unsigned int error : 1;
  unsigned int kind  : 3;
  unsigned int count : 26;
};
```

A read and a write of `kind` used to decompile into unit-sized arithmetic:

```
if ( (*(_DWORD *)&s >> 3) & 7 )
  *p = *p & 0xFFFFFFC7 | (v << 3) & 0x38;
```

When the correct type definitions are available and applied, the decompiler recognizes those masks and shifts and prints the member that they access:

```
if ( s.kind )
  p->kind = v;
```

## What it needs

The proper structure type has to be applied at the access, because the recognition is driven by the type: an expression is rewritten only when the structure declares a bitfield member whose bit offset, width and signedness match exactly what the code extracts. When no member matches, the raw mask and shift are kept, which is also what you see when the type is missing or wrong.

The recognition works the same way on every processor supported by the decompiler. The dedicated bitfield instructions (ARM64 `UBFX`/`SBFX`/`BFI`, PowerPC `rlwinm`/`rlwimi`, MIPS `EXT`/`INS`, RISC-V `Zbs`) are all lowered to plain shift and mask microcode before this point, so the recognition is not processor-specific.

## What is recognized

* reads, signed and unsigned, including a single-bit test and a field tested through the sign of its unit
* reads that the compiler scaled by a power of two, folding the scaling into the extraction: `4 * fe->FuncLen` rather than `(*((_DWORD *)v1 + 1) >> 6) & 0xFFFFFC`
* reads taken from a copy of the unit that the compiler loads once into a register and then extracts one or more fields from
* writes and read-modify-write updates, including the compound forms: `p->cnt += n`, `++p->cnt`, `p->f ^= v`
* a store that packs several fields of one unit at once, which is split into one assignment per field
* accesses narrower than the storage unit, such as a byte load covering a field at the edge of a 4-byte unit
* fields reached through a union, when exactly one alternative declares a matching bitfield
* a field copied from another structure, where the compiler emitted no mask because the store truncates the value anyway

## When the raw form is kept

The rewrite is deliberately conservative. The mask and shift stay as they are when:

* no declared member matches the extracted bit range, its width or its signedness
* the mask is not exactly the field's mask, or it spans two members
* the member is unnamed, or a zero-width bitfield
* the access reaches outside the declared storage unit
* more than one union alternative would match, or you have selected a union view at that address
* the structure is packed and a narrow access does not identify its storage unit unambiguously

## Working with the members

A recognized access is an ordinary member access, so renaming the member, listing its cross-references and jumping to its declaration all work on it, at bit granularity: two members sharing one storage unit are told apart.

## Allocation order

A compiler allocates the members of a bitfield from one end of the storage unit or the other, and this is independent of the byte order. A structure follows the byte order of the database unless it says otherwise: least significant bit first on a little-endian database, most significant bit first on a big-endian one.

A structure that allocates from the other end carries the `__invbf` attribute and prints with it:

```
struct __invbf IMAGE_RESOURCE_DIRECTORY_ENTRY
{
  unsigned int NameOffset : 31;
  unsigned int NameIsString : 1;
};
```

There is no database-wide setting: the decompiler takes the order from the structure that *declares* the bitfields, which is often an inner structure of the one being indexed.

When the types come from a PDB, the order is recovered from the debug information. When you write the declaration yourself, use either `__invbf` or the `#pragma bitfield_order` directive, which both parsers accept:

```
#pragma bitfield_order(push, lsb_to_msb)
struct GPU_REGISTER { unsigned int lo : 8; unsigned int hi : 24; };
#pragma bitfield_order(pop)
```

The directive takes `lsb_to_msb`, `msb_to_lsb` or `default`, and `push`/`pop` to nest. A structure declared under an order that differs from the database default comes out with `__invbf` set.

The attribute travels with the type, so a type library built from headers that set the order records it as well. The libraries that predate it do not, and neither do the databases populated from them: those structures follow the byte order until their types are re-imported.

## Turning it off

The recognition is on by default. To switch it off, untick **Decompile bitfield accesses** in **Edit → Plugins → Hex-Rays Decompiler Options → Options 2**, or clear `HO_BITFIELD_ACCESS` in the [`HEXOPTIONS`](/ida-9.5/core/decompiler/reference/config.md) mask of `hexrays.cfg`.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.hex-rays.com/ida-9.5/core/decompiler/concepts/bitfield-accesses.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
