arch/x86/lib/insn.c
Source file repositories/reference/linux-study-clean/arch/x86/lib/insn.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/lib/insn.c- Extension
.c- Size
- 19191 bytes
- Lines
- 793
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/string.hstring.hasm/inat.hasm/insn.hlinux/unaligned.hlinux/errno.hlinux/kconfig.hasm/emulate_prefix.h
Detected Declarations
function insn_initfunction __insn_get_emulate_prefixfunction insn_get_emulate_prefixfunction thefunction bytefunction insn_get_modrmfunction insn_rip_relativefunction insn_get_sibfunction insn_get_displacementfunction __get_moffsetfunction __get_immv32function __get_immvfunction __get_immptrfunction insn_get_immediatefunction insn_get_lengthfunction insn_completefunction insn_decode
Annotated Snippet
if (inat_is_address_size_prefix(attr)) {
/* address size switches 2/4 or 4/8 */
if (insn->x86_64)
insn->addr_bytes ^= 12;
else
insn->addr_bytes ^= 6;
} else if (inat_is_operand_size_prefix(attr)) {
/* oprand size switches 2/4 */
insn->opnd_bytes ^= 6;
}
found:
prefixes->nbytes++;
insn->next_byte++;
lb = b;
b = peek_next(insn_byte_t, insn);
attr = inat_get_opcode_attribute(b);
}
/* Set the last prefix */
if (lb && lb != insn->prefixes.bytes[3]) {
if (unlikely(insn->prefixes.bytes[3])) {
/* Swap the last prefix */
b = insn->prefixes.bytes[3];
for (i = 0; i < nb; i++)
if (prefixes->bytes[i] == lb)
insn_set_byte(prefixes, i, b);
}
insn_set_byte(&insn->prefixes, 3, lb);
}
/* Decode REX prefix */
if (insn->x86_64) {
b = peek_next(insn_byte_t, insn);
attr = inat_get_opcode_attribute(b);
if (inat_is_rex_prefix(attr)) {
insn_field_set(&insn->rex_prefix, b, 1);
insn->next_byte++;
if (X86_REX_W(b))
/* REX.W overrides opnd_size */
insn->opnd_bytes = 8;
} else if (inat_is_rex2_prefix(attr)) {
insn_set_byte(&insn->rex_prefix, 0, b);
b = peek_nbyte_next(insn_byte_t, insn, 1);
insn_set_byte(&insn->rex_prefix, 1, b);
insn->rex_prefix.nbytes = 2;
insn->next_byte += 2;
if (X86_REX_W(b))
/* REX.W overrides opnd_size */
insn->opnd_bytes = 8;
insn->rex_prefix.got = 1;
goto vex_end;
}
}
insn->rex_prefix.got = 1;
/* Decode VEX/XOP prefix */
b = peek_next(insn_byte_t, insn);
if (inat_is_vex_prefix(attr) || inat_is_xop_prefix(attr)) {
insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
if (inat_is_xop_prefix(attr) && X86_MODRM_REG(b2) == 0) {
/* Grp1A.0 is always POP Ev */
goto vex_end;
} else if (!insn->x86_64) {
/*
* In 32-bits mode, if the [7:6] bits (mod bits of
* ModRM) on the second byte are not 11b, it is
* LDS or LES or BOUND.
*/
if (X86_MODRM_MOD(b2) != 3)
goto vex_end;
}
insn_set_byte(&insn->vex_prefix, 0, b);
insn_set_byte(&insn->vex_prefix, 1, b2);
if (inat_is_evex_prefix(attr)) {
b2 = peek_nbyte_next(insn_byte_t, insn, 2);
insn_set_byte(&insn->vex_prefix, 2, b2);
b2 = peek_nbyte_next(insn_byte_t, insn, 3);
insn_set_byte(&insn->vex_prefix, 3, b2);
insn->vex_prefix.nbytes = 4;
insn->next_byte += 4;
if (insn->x86_64 && X86_VEX_W(b2))
/* VEX.W overrides opnd_size */
insn->opnd_bytes = 8;
} else if (inat_is_vex3_prefix(attr) || inat_is_xop_prefix(attr)) {
b2 = peek_nbyte_next(insn_byte_t, insn, 2);
insn_set_byte(&insn->vex_prefix, 2, b2);
insn->vex_prefix.nbytes = 3;
insn->next_byte += 3;
if (insn->x86_64 && X86_VEX_W(b2))
/* VEX.W/XOP.W overrides opnd_size */
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/string.h`, `string.h`, `asm/inat.h`, `asm/insn.h`, `linux/unaligned.h`, `linux/errno.h`, `linux/kconfig.h`.
- Detected declarations: `function insn_init`, `function __insn_get_emulate_prefix`, `function insn_get_emulate_prefix`, `function the`, `function byte`, `function insn_get_modrm`, `function insn_rip_relative`, `function insn_get_sib`, `function insn_get_displacement`, `function __get_moffset`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.