diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java index 60703c818e..fc5c915258 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java @@ -306,11 +306,6 @@ public class NeLoader extends AbstractLibrarySupportLoader { } } - private int getNextAvailableSegment(Program program) { - Address addr = program.getMemory().getMaxAddress(); - return ((int) addr.getOffset() >> 4) + 1; - } - private void processResourceTable(MessageLog log, Program program, ResourceTable rt, SegmentedAddressSpace space, TaskMonitor monitor) throws IOException { Listing listing = program.getListing(); @@ -326,7 +321,7 @@ public class NeLoader extends AbstractLibrarySupportLoader { Resource[] resources = type.getResources(); for (Resource resource : resources) { - int segidx = getNextAvailableSegment(program); + int segidx = space.getNextOpenSegment(program.getMemory().getMaxAddress()); Address addr = space.getAddress(segidx, 0); try { @@ -417,7 +412,7 @@ public class NeLoader extends AbstractLibrarySupportLoader { for (LengthStringSet name : names) { String[] callnames = getCallNamesForModule(name.getString(), mrt, st, imp); int length = callnames.length * pointerSize; - int segment = getNextAvailableSegment(program); + int segment = space.getNextOpenSegment(program.getMemory().getMaxAddress()); Address start = space.getAddress(segment, 0); if (length > 0) { // This isn't a real block, just place holder addresses, so don't create an initialized block diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMemoryUtil.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMemoryUtil.java index 2cb1e058ab..0c89c48bec 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMemoryUtil.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMemoryUtil.java @@ -176,10 +176,10 @@ public class ProgramMemoryUtil { MemoryBlock[] blocks = mem.getBlocks(); MemoryBlock[] tmpBlocks = new MemoryBlock[blocks.length]; int j = 0; - for (int i = 0; i < blocks.length; i++) { - if ((blocks[i].isInitialized() && withBytes) || - (!blocks[i].isInitialized() && !withBytes)) { - tmpBlocks[j++] = blocks[i]; + for (MemoryBlock block : blocks) { + if ((block.isInitialized() && withBytes) || + (!block.isInitialized() && !withBytes)) { + tmpBlocks[j++] = block; } } MemoryBlock[] typeBlocks = new MemoryBlock[j]; @@ -297,7 +297,7 @@ public class ProgramMemoryUtil { } // Just looking for the offset into the segment now, not the whole segment/offset pair - if (addrSize == 20) { + if (toAddress instanceof SegmentedAddress) { SegmentedAddress segAddr = (SegmentedAddress) toAddress; currentSegment = (short) segAddr.getSegment(); } @@ -322,10 +322,10 @@ public class ProgramMemoryUtil { if (toAddress instanceof SegmentedAddress) { short offsetShort = memory.getShort(a); offsetShort &= offsetShort & 0xffff; - SegmentedAddress sega = ((SegmentedAddress) a); - short shortSega = (short) (sega.getSegment()); - shortSega &= shortSega & 0xffff; // this is checking to see if the ref is in the same segment as the toAddr - not sure this is needed anymore + // SegmentedAddress sega = ((SegmentedAddress) a); + // short shortSega = (short) (sega.getSegment()); + // shortSega &= shortSega & 0xffff; // if (offsetShort == shortCurrentOffset) { //*** commenting this out is making it find the instances of 46 01's not the 0a 00's - closer though // check for the case where the reference includes both the segment and offset @@ -441,8 +441,9 @@ public class ProgramMemoryUtil { } for (ReferenceAddressPair rap : directReferenceList) { - if (monitor.isCancelled()) + if (monitor.isCancelled()) { return null; + } Address fromAddr = rap.getSource(); if (!results.contains(fromAddr)) { results.add(fromAddr); @@ -624,18 +625,18 @@ public class ProgramMemoryUtil { byte maskBytes[] = null; MemoryBlock[] blocks = memory.getBlocks(); - for (int i = 0; i < blocks.length; i++) { - if (!blocks[i].isInitialized()) { + for (MemoryBlock block : blocks) { + if (!block.isInitialized()) { continue; } if (memoryRange != null && - !memoryRange.intersects(blocks[i].getStart(), blocks[i].getEnd())) { + !memoryRange.intersects(block.getStart(), block.getEnd())) { // skip blocks which do not correspond to currentSeg continue; } - Address start = blocks[i].getStart(); - Address end = blocks[i].getEnd(); + Address start = block.getStart(); + Address end = block.getEnd(); Address found = null; while (true) { monitor.checkCanceled(); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/ProtectedAddressSpace.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/ProtectedAddressSpace.java index d5634a5ae0..62022d15de 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/ProtectedAddressSpace.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/ProtectedAddressSpace.java @@ -35,6 +35,7 @@ public class ProtectedAddressSpace extends SegmentedAddressSpace { offsetMask = 1; offsetMask <<= offsetSize; offsetMask -= 1; + maxAddress = getUncheckedAddress(maxOffset); } @Override @@ -64,4 +65,11 @@ public class ProtectedAddressSpace extends SegmentedAddressSpace { protected SegmentedAddress getAddressInSegment(long flat, int preferredSegment) { return null; // The segment cannot be changed as the flat explicitly encodes it } + + @Override + public int getNextOpenSegment(Address addr) { + int res = getDefaultSegmentFromFlat(addr.getOffset()); + res += 1; + return res; + } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/SegmentedAddressSpace.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/SegmentedAddressSpace.java index f999f56729..71f7581304 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/SegmentedAddressSpace.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/SegmentedAddressSpace.java @@ -46,10 +46,9 @@ public class SegmentedAddressSpace extends GenericAddressSpace { */ protected SegmentedAddressSpace(String name, int size, int unique) { super(name, size, TYPE_RAM, unique); - spaceSize = 1; - spaceSize <<= size; - maxOffset = spaceSize - 1; - maxAddress = getUncheckedAddress(maxOffset); +// maxAddress = getUncheckedAddress(maxOffset); + // Constructors for derived classes that call this will + // need to reconstruct maxAddress themselves. } /** @@ -318,6 +317,18 @@ public class SegmentedAddressSpace extends GenericAddressSpace { return new SegmentedAddress(this, segment, segmentOffset); } + /** + * Get the segment index for the first segment whose start address + * comes after the given address + * @param addr is the given address + * @return the segment index + */ + public int getNextOpenSegment(Address addr) { + int res = (int) addr.getOffset(); // The "flat" offset (presumably real-mode encoded) + res = (res >> 4) + 1; + return res; + } + /** * * @see ghidra.program.model.address.AddressSpace#getPhysicalSpace() diff --git a/Ghidra/Processors/x86/certification.manifest b/Ghidra/Processors/x86/certification.manifest index b499e4cc9a..3d21aaea4a 100644 --- a/Ghidra/Processors/x86/certification.manifest +++ b/Ghidra/Processors/x86/certification.manifest @@ -27,6 +27,7 @@ data/languages/rdseed.sinc||GHIDRA||||END| data/languages/sgx.sinc||GHIDRA||||END| data/languages/sha.sinc||GHIDRA||||END| data/languages/smx.sinc||GHIDRA||||END| +data/languages/x86-16-real.pspec||GHIDRA||||END| data/languages/x86-16.cspec||GHIDRA||||END| data/languages/x86-16.pspec||GHIDRA||||END| data/languages/x86-64-gcc.cspec||GHIDRA||||END| diff --git a/Ghidra/Processors/x86/data/languages/ia.sinc b/Ghidra/Processors/x86/data/languages/ia.sinc index 57491cf9c4..107576cc58 100644 --- a/Ghidra/Processors/x86/data/languages/ia.sinc +++ b/Ghidra/Processors/x86/data/languages/ia.sinc @@ -1387,10 +1387,7 @@ check_Rmr32_dest: is epsilon { } check_rm32_dest: is epsilon { } check_EAX_dest: is epsilon { } -# The far addresses listed here actually specify the CS segment to use -# but we do not model changing the CS segment in protected mode -# so we just use the offset portion of the address -ptr1616: reloc is imm16; j16 [ reloc = j16*16 + imm16; ] { CS = j16; export *[ram]:4 reloc; } +ptr1616: reloc is imm16; j16 [ reloc = j16*0x10000 + imm16; ] { CS = j16; export *[ram]:4 reloc; } ptr1632: j16":"imm32 is imm32; j16 { CS = j16; export *:4 imm32; } diff --git a/Ghidra/Processors/x86/data/languages/x86-16-real.pspec b/Ghidra/Processors/x86/data/languages/x86-16-real.pspec new file mode 100644 index 0000000000..d618652472 --- /dev/null +++ b/Ghidra/Processors/x86/data/languages/x86-16-real.pspec @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/x86/data/languages/x86-16.pspec b/Ghidra/Processors/x86/data/languages/x86-16.pspec index b1c2038b07..78b5d5962c 100644 --- a/Ghidra/Processors/x86/data/languages/x86-16.pspec +++ b/Ghidra/Processors/x86/data/languages/x86-16.pspec @@ -1,11 +1,13 @@ + + - + diff --git a/Ghidra/Processors/x86/data/languages/x86.ldefs b/Ghidra/Processors/x86/data/languages/x86.ldefs index 475f8b8a23..20f59a3a62 100644 --- a/Ghidra/Processors/x86/data/languages/x86.ldefs +++ b/Ghidra/Processors/x86/data/languages/x86.ldefs @@ -47,19 +47,31 @@ variant="Real Mode" version="2.8" slafile="x86.sla" - processorspec="x86-16.pspec" + processorspec="x86-16-real.pspec" manualindexfile="../manuals/x86.idx" id="x86:LE:16:Real Mode"> Intel/AMD 16-bit x86 Real Mode - + + Intel/AMD 16-bit x86 Protected Mode + + +