NationalSecurityAgency/ghidra · error · IllegalArgumentException

Length would cause address overflow in program

Error message

Length would cause address overflow in program

What it means

The companion check in addMapping(): length-1 must not exceed the maximum address of the destination PROGRAM's address space (unsigned). Even if the trace side fits, a length that runs the destination range past the program space's max address throws IllegalArgumentException("Length would cause address overflow in program").

Source

Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java:131

			throw new IllegalArgumentException(
				"Mapping destination cannot be a " + TraceProgramView.class.getSimpleName());
		}
		TraceStaticMappingManager manager = from.getTrace().getStaticMappingManager();
		URL toURL = ProgramURLUtils.getUrlFromProgram(tp);
		if (toURL == null) {
			noProject(DebuggerStaticMappingUtils.class);
		}
		Address fromAddress = from.getAddress();
		Address toAddress = to.getByteAddress();
		long maxFromLengthMinus1 =
			fromAddress.getAddressSpace().getMaxAddress().subtract(fromAddress);
		long maxToLengthMinus1 =
			toAddress.getAddressSpace().getMaxAddress().subtract(toAddress);
		if (Long.compareUnsigned(length - 1, maxFromLengthMinus1) > 0) {
			throw new IllegalArgumentException("Length would cause address overflow in trace");
		}
		if (Long.compareUnsigned(length - 1, maxToLengthMinus1) > 0) {
			throw new IllegalArgumentException("Length would cause address overflow in program");
		}
		Address end = fromAddress.addWrap(length - 1);
		// Also check end in the destination
		AddressRangeImpl range = new AddressRangeImpl(fromAddress, end);
		Lifespan fromLifespan = from.getLifespan();
		if (truncateExisting) {
			long truncEnd = fromLifespan.lmin() - 1;
			for (TraceStaticMapping existing : List
					.copyOf(manager.findAllOverlapping(range, fromLifespan))) {
				existing.delete();
				if (fromLifespan.minIsFinite() &&
					Lifespan.DOMAIN.compare(existing.getStartSnap(), truncEnd) <= 0) {
					manager.add(existing.getTraceAddressRange(),
						Lifespan.span(existing.getStartSnap(), truncEnd),
						existing.getStaticProgramURL(), existing.getStaticAddress());
				}
			}
		}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Clamp length to toAddress space bounds: Math.min(length, maxTo.subtract(toAddress) + 1).
  2. Recompute length as an unsigned byte count and verify it fits both source and destination spaces.
  3. If destination and source spaces differ in size, map a smaller sub-range that fits the destination.

Example fix

// before
DebuggerStaticMappingUtils.addMapping(from, to, traceLength, false); // overflows program space

// after
Address maxTo = to.getByteAddress().getAddressSpace().getMaxAddress();
long maxLenTo = maxTo.subtract(to.getByteAddress()) + 1;
long length = Math.min(traceLength, maxLenTo);
DebuggerStaticMappingUtils.addMapping(from, to, length, false);
Defensive patterns

Strategy: validation

Validate before calling

// Clamp length to the destination program address space before addMapping
Address toAddr = to.getByteAddress();
long maxLenTo = toAddr.getAddressSpace().getMaxAddress().subtract(toAddr) + 1;
long safeLength = Math.min(length, maxLenTo);
if (Long.compareUnsigned(length - 1, maxLenTo - 1) > 0) {
    length = safeLength;
}

Type guard

public static boolean lengthFitsProgram(Address toAddr, long length) {
    long maxLen = toAddr.getAddressSpace().getMaxAddress().subtract(toAddr) + 1;
    return Long.compareUnsigned(length, maxLen) <= 0;
}

Try / catch

try {
    DebuggerStaticMappingUtils.addMapping(from, to, length, false);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("overflow in program")) {
        long maxLen = to.getByteAddress().getAddressSpace().getMaxAddress()
            .subtract(to.getByteAddress()) + 1;
        DebuggerStaticMappingUtils.addMapping(from, to, Math.min(length, maxLen), false);
    } else throw e;
}

Prevention

When it happens

Trigger: Destination program has a smaller address space than the trace (e.g. mapping into a program whose space is narrower). Length derived from the trace range but the destination starts near the top of its space. Off-by-one or unit confusion producing an oversized length.

Common situations: Mapping a large trace region into a program near the end of its address space. Destination program built from a different language with a smaller pointer width. Miscomputed length passed through from a module map.

Related errors


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