diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py index 5bc251cf57..e24d924c55 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py @@ -495,10 +495,11 @@ def put_bytes(start, end, pages, is_mi, from_tty): def eval_address(address): + max_addr = util.compute_max_addr() if isinstance(address, int): - return address + return address & max_addr try: - return int(gdb.parse_and_eval(address)) + return int(gdb.parse_and_eval(address)) & max_addr except gdb.error as e: raise gdb.GdbError("Cannot convert '{}' to address".format(address)) diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/util.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/util.py index 9a81fc3f05..bb58f7defa 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/util.py +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/util.py @@ -110,12 +110,12 @@ class ModuleInfoReader(object): n = mat['name'] return None if mat is None else mat['name'] - def section_from_line(self, line): + def section_from_line(self, line, max_addr): mat = self.section_pattern.fullmatch(line) if mat is None: return None - start = try_hexint(mat['vmaS'], 'section start') - end = try_hexint(mat['vmaE'], 'section end') + start = try_hexint(mat['vmaS'], 'section start') & max_addr + end = try_hexint(mat['vmaE'], 'section end') & max_addr offset = try_hexint(mat['offset'], 'section offset') name = mat['name'] attrs = [a for a in mat['attrs'].split(' ') if a != ''] @@ -133,6 +133,7 @@ class ModuleInfoReader(object): modules = {} index = Index(REGION_INFO_READER.get_regions()) out = gdb.execute(self.cmd, to_string=True) + max_addr = compute_max_addr() name = None sections = None for line in out.split('\n'): @@ -146,7 +147,7 @@ class ModuleInfoReader(object): if name is None: # Don't waste time parsing if no module continue - s = self.section_from_line(line) + s = self.section_from_line(line, max_addr) if s is not None: if s.name in sections: s = s.better(sections[s.name]) @@ -197,12 +198,12 @@ MODULE_INFO_READER = _choose_module_info_reader() REGIONS_CMD = 'info proc mappings' REGION_PATTERN = re.compile("\\s*" + - "0x(?P[0-9,A-F,a-f]+)\\s+" + - "0x(?P[0-9,A-F,a-f]+)\\s+" + - "0x(?P[0-9,A-F,a-f]+)\\s+" + - "0x(?P[0-9,A-F,a-f]+)\\s+" + - "((?P[rwsxp\\-]+)?\\s+)?" + - "(?P.*)") + "0x(?P[0-9,A-F,a-f]+)\\s+" + + "0x(?P[0-9,A-F,a-f]+)\\s+" + + "0x(?P[0-9,A-F,a-f]+)\\s+" + + "0x(?P[0-9,A-F,a-f]+)\\s+" + + "((?P[rwsxp\\-]+)?\\s+)?" + + "(?P.*)") class Region(namedtuple('BaseRegion', ['start', 'end', 'offset', 'perms', 'objfile'])): @@ -212,13 +213,13 @@ class Region(namedtuple('BaseRegion', ['start', 'end', 'offset', 'perms', 'objfi class RegionInfoReader(object): cmd = REGIONS_CMD region_pattern = REGION_PATTERN - - def region_from_line(self, line): + + def region_from_line(self, line, max_addr): mat = self.region_pattern.fullmatch(line) if mat is None: return None - start = try_hexint(mat['start'], 'region start') - end = try_hexint(mat['end'], 'region end') + start = try_hexint(mat['start'], 'region start') & max_addr + end = try_hexint(mat['end'], 'region end') & max_addr offset = try_hexint(mat['offset'], 'region offset') perms = self.get_region_perms(mat) objfile = mat['objfile'] @@ -228,10 +229,11 @@ class RegionInfoReader(object): regions = [] try: out = gdb.execute(self.cmd, to_string=True) + max_addr = compute_max_addr() except: return regions for line in out.split('\n'): - r = self.region_from_line(line) + r = self.region_from_line(line, max_addr) if r is None: continue regions.append(r) @@ -239,14 +241,14 @@ class RegionInfoReader(object): def full_mem(self): # TODO: This may not work for Harvard architectures - sizeptr = int(gdb.parse_and_eval('sizeof(void*)')) * 8 - return Region(0, 1 << sizeptr, 0, None, 'full memory') + max_addr = compute_max_addr() + return Region(0, max_addr+1, 0, None, 'full memory') def have_changed(self, regions): if len(regions) == 1 and regions[0].objfile == 'full memory': return False, None new_regions = self.get_regions() - if new_regions == regions: + if new_regions == regions and len(new_regions) > 0: return False, None return True, new_regions @@ -396,3 +398,7 @@ def selected_frame(): except Exception as e: print("No selected frame") return None + + +def compute_max_addr(): + return (1 << (int(gdb.parse_and_eval("sizeof(void*)")) * 8)) - 1 diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapProposal.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapProposal.java index d9a183771a..2ffe80c51c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapProposal.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapProposal.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -63,6 +63,9 @@ public abstract class AbstractMapProposal> } protected double computeLengthScore() { + if (fromRange == null) { + return 0; + } long fLen = fromRange.getLength(); long tLen = toRange.getLength(); for (int bitsmatched = 64; bitsmatched > 0; bitsmatched--) { diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java index e75fa9fa27..cd376dcbfb 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java @@ -653,8 +653,8 @@ public class DBTraceMemorySpace int pos = buf.position(); try (LockHold hold = LockHold.lock(lock.writeLock())) { - ByteBuffer oldBytes = ByteBuffer.allocate(buf.remaining()); - getBytes(snap, start, oldBytes); + ByteBuffer oldBuf = ByteBuffer.allocate(buf.remaining()); + getBytes(snap, start, oldBuf); OutSnap lastSnap = new OutSnap(snap); Set changed = new HashSet<>(); @@ -665,16 +665,18 @@ public class DBTraceMemorySpace // Read back the written bytes and fire event byte[] bytes = new byte[result]; + byte[] oldBytes = new byte[result]; buf.get(pos, bytes); + oldBuf.get(0, oldBytes); ImmutableTraceAddressSnapRange tasr = new ImmutableTraceAddressSnapRange(start, start.add(result - 1), snap, lastSnap.snap); trace.setChanged(new TraceChangeRecord<>(TraceEvents.BYTES_CHANGED, this, tasr, - oldBytes.array(), bytes)); + oldBytes, bytes)); // Fixup affected code units DBTraceCodeSpace codeSpace = trace.getCodeManager().get(this, false); if (codeSpace != null) { - codeSpace.bytesChanged(changed, snap, start, oldBytes.array(), bytes); + codeSpace.bytesChanged(changed, snap, start, oldBytes, bytes); } // Clear program view caches trace.updateViewsBytesChanged(tasr.getRange());