{"record":{"id":"e239fab8a4e85abd","repo":"NationalSecurityAgency/ghidra","slug":"length-would-cause-address-overflow-in-program","errorCode":null,"errorMessage":"Length would cause address overflow in program","messagePattern":"Length would cause address overflow in program","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java","lineNumber":131,"sourceCode":"\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\"Mapping destination cannot be a \" + TraceProgramView.class.getSimpleName());\n\t\t}\n\t\tTraceStaticMappingManager manager = from.getTrace().getStaticMappingManager();\n\t\tURL toURL = ProgramURLUtils.getUrlFromProgram(tp);\n\t\tif (toURL == null) {\n\t\t\tnoProject(DebuggerStaticMappingUtils.class);\n\t\t}\n\t\tAddress fromAddress = from.getAddress();\n\t\tAddress toAddress = to.getByteAddress();\n\t\tlong maxFromLengthMinus1 =\n\t\t\tfromAddress.getAddressSpace().getMaxAddress().subtract(fromAddress);\n\t\tlong maxToLengthMinus1 =\n\t\t\ttoAddress.getAddressSpace().getMaxAddress().subtract(toAddress);\n\t\tif (Long.compareUnsigned(length - 1, maxFromLengthMinus1) > 0) {\n\t\t\tthrow new IllegalArgumentException(\"Length would cause address overflow in trace\");\n\t\t}\n\t\tif (Long.compareUnsigned(length - 1, maxToLengthMinus1) > 0) {\n\t\t\tthrow new IllegalArgumentException(\"Length would cause address overflow in program\");\n\t\t}\n\t\tAddress end = fromAddress.addWrap(length - 1);\n\t\t// Also check end in the destination\n\t\tAddressRangeImpl range = new AddressRangeImpl(fromAddress, end);\n\t\tLifespan fromLifespan = from.getLifespan();\n\t\tif (truncateExisting) {\n\t\t\tlong truncEnd = fromLifespan.lmin() - 1;\n\t\t\tfor (TraceStaticMapping existing : List\n\t\t\t\t\t.copyOf(manager.findAllOverlapping(range, fromLifespan))) {\n\t\t\t\texisting.delete();\n\t\t\t\tif (fromLifespan.minIsFinite() &&\n\t\t\t\t\tLifespan.DOMAIN.compare(existing.getStartSnap(), truncEnd) <= 0) {\n\t\t\t\t\tmanager.add(existing.getTraceAddressRange(),\n\t\t\t\t\t\tLifespan.span(existing.getStartSnap(), truncEnd),\n\t\t\t\t\t\texisting.getStaticProgramURL(), existing.getStaticAddress());\n\t\t\t\t}\n\t\t\t}\n\t\t}","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java#L113-L149","documentation":"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\").","triggerScenarios":"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.","commonSituations":"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.","solutions":["Clamp length to toAddress space bounds: Math.min(length, maxTo.subtract(toAddress) + 1).","Recompute length as an unsigned byte count and verify it fits both source and destination spaces.","If destination and source spaces differ in size, map a smaller sub-range that fits the destination."],"exampleFix":"// before\nDebuggerStaticMappingUtils.addMapping(from, to, traceLength, false); // overflows program space\n\n// after\nAddress maxTo = to.getByteAddress().getAddressSpace().getMaxAddress();\nlong maxLenTo = maxTo.subtract(to.getByteAddress()) + 1;\nlong length = Math.min(traceLength, maxLenTo);\nDebuggerStaticMappingUtils.addMapping(from, to, length, false);","handlingStrategy":"validation","validationCode":"// Clamp length to the destination program address space before addMapping\nAddress toAddr = to.getByteAddress();\nlong maxLenTo = toAddr.getAddressSpace().getMaxAddress().subtract(toAddr) + 1;\nlong safeLength = Math.min(length, maxLenTo);\nif (Long.compareUnsigned(length - 1, maxLenTo - 1) > 0) {\n    length = safeLength;\n}","typeGuard":"public static boolean lengthFitsProgram(Address toAddr, long length) {\n    long maxLen = toAddr.getAddressSpace().getMaxAddress().subtract(toAddr) + 1;\n    return Long.compareUnsigned(length, maxLen) <= 0;\n}","tryCatchPattern":"try {\n    DebuggerStaticMappingUtils.addMapping(from, to, length, false);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"overflow in program\")) {\n        long maxLen = to.getByteAddress().getAddressSpace().getMaxAddress()\n            .subtract(to.getByteAddress()) + 1;\n        DebuggerStaticMappingUtils.addMapping(from, to, Math.min(length, maxLen), false);\n    } else throw e;\n}","preventionTips":["Check the destination program's address space width; it may be smaller than the trace's.","Compute length as an unsigned byte count relative to the destination start.","Clip ranges to the narrower of source/destination spaces."],"tags":["static-mapping","address-overflow","validation","arithmetic"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}