NationalSecurityAgency/ghidra · error · IllegalArgumentException

Register {register} does not map to space {space}'s physical

Error message

Register {register} does not map to space {space}'s physical space ({space.getPhysicalSpace})

What it means

Thrown by getConventionalRegisterRange when a register that lives in the register address space is mapped (via mapGuestToHost) to a host address space that does not match the requested space's physical space. This indicates a mismatch between the guest register's mapped host location and the overlay/physical space the caller asked for. The method is validating that a guest-platform register, after translation to host coordinates, still belongs to the correct physical address space before returning an overlay-adjusted range.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/guest/InternalTracePlatform.java:69

	DBTraceGuestLanguage getLanguageEntry();

	@Override
	default AddressFactory getAddressFactory() {
		return TracePlatform.super.getAddressFactory();
	}

	@Override
	default AddressRange getConventionalRegisterRange(AddressSpace space, Register register) {
		AddressRange result = mapGuestToHost(TraceRegisterUtils.rangeForRegister(register));
		if (result == null) {
			throw new IllegalArgumentException("Register " + register + " is not mapped");
		}
		if (space == null) {
			return result;
		}
		if (register.getAddressSpace().isRegisterSpace()) {
			if (result.getAddressSpace() != space.getPhysicalSpace()) {
				throw new IllegalArgumentException(
					"Register " + register + " does not map to space " + space +
						"'s physical space (" + space.getPhysicalSpace() + ")");
			}
			return new AddressRangeImpl(
				space.getOverlayAddress(result.getMinAddress()),
				space.getOverlayAddress(result.getMaxAddress()));
		}
		if (result.getAddressSpace() != space) {
			throw new IllegalArgumentException(
				"Memory-mapped register " + register + " does not map to space " + space);
		}
		return result;
	}

	default List<String> listRegNames(Register register) {
		Set<String> result = new LinkedHashSet<>();
		result.add(register.getName());
		result.add(register.getName().toUpperCase());

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Verify that the 'space' argument matches the address space where the register actually maps on the host — call register.getAddressSpace() and compare its physical space to space.getPhysicalSpace() before invoking getConventionalRegisterRange.
  2. If you need the host register range regardless of overlay, pass null for the 'space' parameter (the method returns the raw host range when space == null).
  3. Ensure the register object comes from the same platform/language that produced the mapping — do not cross guest platforms.
  4. Check for stale register mappings after upgrading the guest language definition (.sleigh / .ldefs).

Example fix

// before
AddressRange range = platform.getConventionalRegisterRange(overlaySpace, register);

// after — pass null to get the raw host mapping, or verify the space first
AddressSpace regPhys = register.getAddressSpace().getPhysicalSpace();
if (regPhys == overlaySpace.getPhysicalSpace()) {
    AddressRange range = platform.getConventionalRegisterRange(overlaySpace, register);
} else {
    AddressRange range = platform.getConventionalRegisterRange(null, register);
}
Defensive patterns

Strategy: validation

Validate before calling

// Before calling getConventionalRegisterRange
AddressSpace regSpace = register.getAddressSpace();
if (regSpace.isRegisterSpace()) {
    if (space != null && regSpace.getPhysicalSpace() != space.getPhysicalSpace()) {
        // pass null to get raw host range, or fix the space argument
        return platform.getConventionalRegisterRange(null, register);
    }
}
return platform.getConventionalRegisterRange(space, register);

Type guard

// Check register/space compatibility before the call
static boolean registerSpaceMatches(Register register, AddressSpace space) {
    if (space == null) return true;
    if (register.getAddressSpace().isRegisterSpace()) {
        return register.getAddressSpace().getPhysicalSpace() == space.getPhysicalSpace();
    }
    return register.getAddressSpace() == space;
}

Try / catch

try {
    return platform.getConventionalRegisterRange(space, register);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("does not map to space")) {
        // Fallback: get raw host mapping without space validation
        return platform.getConventionalRegisterRange(null, register);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling platform.getConventionalRegisterRange(space, register) where 'space' is an overlay space (or any space with a distinct physical space) and 'register' is a true register-space register whose guest-to-host mapping resolves into a different physical space than space.getPhysicalSpace(). This happens when the caller passes a register whose host-side mapping lives in register space but the supplied 'space' parameter points to a memory overlay space (or vice versa).

Common situations: Mixing up overlay spaces and their physical spaces when querying register values; using a register obtained from the wrong guest platform; passing a memory-overlay space where a register-space-derived space was expected; incorrect TraceRegisterUtils mappings after a language/platform version change that altered register layouts.

Related errors


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