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
+
+
+