NationalSecurityAgency/ghidra · error · ValueError

Invalid byte_order: {byte_order}

Error message

Invalid byte_order: {byte_order}

What it means

Thrown as a ValueError by DefaultRegisterMapper.__init__ in the gdb agent when the byte_order argument is not one of the two accepted strings 'big' or 'little'. The constructor validates byte ordering up front because it determines how register byte sequences are serialized.

Source

Thrown at Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py:253

        raise ValueError(f"Address {address} is not in inferior {inf.num}")


DEFAULT_MEMORY_MAPPER = DefaultMemoryMapper('ram')

memory_mappers: Dict[str, DefaultMemoryMapper] = {}


def compute_memory_mapper(lang: str) -> DefaultMemoryMapper:
    if not lang in memory_mappers:
        return DEFAULT_MEMORY_MAPPER
    return memory_mappers[lang]


class DefaultRegisterMapper(object):

    def __init__(self, byte_order: str) -> None:
        if not byte_order in ['big', 'little']:
            raise ValueError(f"Invalid byte_order: {byte_order}")
        self.byte_order = byte_order

    def map_name(self, inf: gdb.Inferior, name: str):
        return name

    def convert_value(self, value: gdb.Value,
                      type: Optional[gdb.Type] = None) -> bytes:
        if type is None:
            type = value.dynamic_type.strip_typedefs()
        l = type.sizeof
        # l - 1 because array() takes the max index, inclusive
        # NOTE: Might like to pre-lookup 'unsigned char', but it depends on the
        # architecture *at the time of lookup*.
        cv = value.cast(gdb.lookup_type('unsigned char').array(l - 1))
        rng: Sequence[int] = range(l)
        it = reversed(rng) if self.byte_order == 'little' else rng
        result = bytes(cv[i] for i in it)
        return result

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Pass exactly 'big' or 'little' as the byte_order string.
  2. Normalize arch endianness before constructing the mapper: map 'big-endian'/'BE'/1 to 'big' and 'little-endian'/'LE'/0 to 'little'.
  3. If endianness is unknown, default to 'little' for x86/x64 or detect via gdb.execute('show endian').

Example fix

// before
mapper = DefaultRegisterMapper(gdb.execute('show endian', to_string=True))
// after
endian_raw = gdb.execute('show endian', to_string=True)
byte_order = 'little' if 'little' in endian_raw else 'big'
mapper = DefaultRegisterMapper(byte_order)
Defensive patterns

Strategy: validation

Validate before calling

def normalize_byte_order(byte_order: str) -> str:
    bo = byte_order.strip().lower()
    aliases = {
        'big': 'big', 'big-endian': 'big', 'be': 'big', 'msb': 'big', '1': 'big',
        'little': 'little', 'little-endian': 'little', 'le': 'little', 'lsb': 'little', '0': 'little',
    }
    if bo not in aliases:
        raise ValueError(f"Cannot normalize byte_order: {byte_order!r}")
    return aliases[bo]

mapper = DefaultRegisterMapper(normalize_byte_order(raw_endian))

Type guard

def is_valid_byte_order(byte_order: str) -> bool:
    return byte_order in ('big', 'little')

Try / catch

try:
    mapper = DefaultRegisterMapper(byte_order)
except ValueError as e:
    if 'Invalid byte_order' in str(e):
        byte_order = 'little' if 'little' in byte_order.lower() else 'big'
        mapper = DefaultRegisterMapper(byte_order)
    raise

Prevention

When it happens

Trigger: Calling DefaultRegisterMapper('big-endian'), DefaultRegisterMapper('LE'), DefaultRegisterMapper('none'), or any byte_order string other than exactly 'big' or 'little'. Also fires if None is passed (since None is not in the list).

Common situations: Reading endianness from a config or arch-detection function that returns a different format (e.g. 'big-endian', 'BE', 'little-endian', 0/1); passing a GDB architecture's endian field directly without normalization; defaulting to None when arch detection fails.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/0585a4d98fdbfcfc. Report an issue: GitHub.