mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-29 03:06:57 +08:00
Merge branch 'GP-0_ryanmkurtz_PR-5154_Gravelbones_omf_select'
This commit is contained in:
+4
@@ -27,6 +27,10 @@ public class OmfCommentRecord extends OmfRecord {
|
|||||||
public static final byte COMMENT_CLASS_LIBMOD = (byte) 0xA3;
|
public static final byte COMMENT_CLASS_LIBMOD = (byte) 0xA3;
|
||||||
// Default library cmd
|
// Default library cmd
|
||||||
public static final byte COMMENT_CLASS_DEFAULT_LIBRARY = (byte) 0x9F;
|
public static final byte COMMENT_CLASS_DEFAULT_LIBRARY = (byte) 0x9F;
|
||||||
|
// Watcom compile parameters
|
||||||
|
public static final byte COMMENT_CLASS_WATCOM_SETTINGS = (byte) 0x9b;
|
||||||
|
// Microsoft compile parameters
|
||||||
|
public static final byte COMMENT_CLASS_MICROSOFT_SETTINGS = (byte) 0x9d;
|
||||||
|
|
||||||
private byte commentType;
|
private byte commentType;
|
||||||
private byte commentClass;
|
private byte commentClass;
|
||||||
|
|||||||
+23
-12
@@ -37,6 +37,7 @@ public class OmfFileHeader extends OmfRecord {
|
|||||||
private ArrayList<OmfFixupRecord> fixup = new ArrayList<OmfFixupRecord>();
|
private ArrayList<OmfFixupRecord> fixup = new ArrayList<OmfFixupRecord>();
|
||||||
private ArrayList<OmfSegmentHeader> extraSeg = null; // Holds implied segments that don't have official header record
|
private ArrayList<OmfSegmentHeader> extraSeg = null; // Holds implied segments that don't have official header record
|
||||||
// private OmfModuleEnd endModule = null;
|
// private OmfModuleEnd endModule = null;
|
||||||
|
private boolean format16bit;
|
||||||
|
|
||||||
public OmfFileHeader(BinaryReader reader) throws IOException {
|
public OmfFileHeader(BinaryReader reader) throws IOException {
|
||||||
readRecordHeader(reader);
|
readRecordHeader(reader);
|
||||||
@@ -65,7 +66,7 @@ public class OmfFileHeader extends OmfRecord {
|
|||||||
* @return the string identifying the architecture this object was compiled for
|
* @return the string identifying the architecture this object was compiled for
|
||||||
*/
|
*/
|
||||||
public String getMachineName() {
|
public String getMachineName() {
|
||||||
return "i386"; // This is the only possibility
|
return format16bit ? "16bit" : "32bit";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -250,13 +251,13 @@ public class OmfFileHeader extends OmfRecord {
|
|||||||
* Scan the object file, for the main header and comment records. Other records are parsed but not saved
|
* Scan the object file, for the main header and comment records. Other records are parsed but not saved
|
||||||
* @param reader is the byte stream
|
* @param reader is the byte stream
|
||||||
* @param monitor is checked for cancellation
|
* @param monitor is checked for cancellation
|
||||||
* @param initialCommentsOnly is true if we only want to scan the header and the initial comments,
|
* @param fastscan is true if we only want to scan the header until first seghead,
|
||||||
* @return the header record
|
* @return the header record
|
||||||
* @throws IOException for problems reading program data
|
* @throws IOException for problems reading program data
|
||||||
* @throws OmfException for malformed records
|
* @throws OmfException for malformed records
|
||||||
*/
|
*/
|
||||||
public static OmfFileHeader scan(BinaryReader reader, TaskMonitor monitor,
|
public static OmfFileHeader scan(BinaryReader reader, TaskMonitor monitor, boolean fastscan)
|
||||||
boolean initialCommentsOnly) throws IOException, OmfException {
|
throws IOException, OmfException {
|
||||||
OmfRecord record = OmfRecord.readRecord(reader);
|
OmfRecord record = OmfRecord.readRecord(reader);
|
||||||
if (!(record instanceof OmfFileHeader)) {
|
if (!(record instanceof OmfFileHeader)) {
|
||||||
throw new OmfException("Object file does not start with proper header");
|
throw new OmfException("Object file does not start with proper header");
|
||||||
@@ -274,16 +275,26 @@ public class OmfFileHeader extends OmfRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (record instanceof OmfCommentRecord comment) {
|
if (record instanceof OmfCommentRecord comment) {
|
||||||
byte commentClass = comment.getCommentClass();
|
switch (comment.getCommentClass()) {
|
||||||
if (commentClass == OmfCommentRecord.COMMENT_CLASS_TRANSLATOR) {
|
case OmfCommentRecord.COMMENT_CLASS_TRANSLATOR:
|
||||||
header.translator = comment.getValue();
|
header.translator = comment.getValue();
|
||||||
}
|
break;
|
||||||
else if (commentClass == OmfCommentRecord.COMMENT_CLASS_LIBMOD) {
|
case OmfCommentRecord.COMMENT_CLASS_LIBMOD:
|
||||||
header.libModuleName = comment.getValue();
|
header.libModuleName = comment.getValue();
|
||||||
|
break;
|
||||||
|
case OmfCommentRecord.COMMENT_CLASS_WATCOM_SETTINGS:
|
||||||
|
header.translator = "Watcom";
|
||||||
|
break;
|
||||||
|
case OmfCommentRecord.COMMENT_CLASS_MICROSOFT_SETTINGS:
|
||||||
|
header.translator = "Microsoft";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (initialCommentsOnly) {
|
else if (record instanceof OmfSegmentHeader head) {
|
||||||
break;
|
header.format16bit = head.is16Bit();
|
||||||
|
if (fastscan) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return header;
|
return header;
|
||||||
|
|||||||
+7
@@ -206,6 +206,13 @@ public class OmfSegmentHeader extends OmfRecord {
|
|||||||
return (segAttr >> 2) & 0x7;
|
return (segAttr >> 2) & 0x7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return if 16 or 32 bit segments are used
|
||||||
|
*/
|
||||||
|
public boolean is16Bit() {
|
||||||
|
return (segAttr & 1) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this block uses filler other than zero bytes
|
* @return true if this block uses filler other than zero bytes
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -70,6 +70,12 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||||||
if (record.startsWith("CodeGear")) {
|
if (record.startsWith("CodeGear")) {
|
||||||
return "codegearcpp";
|
return "codegearcpp";
|
||||||
}
|
}
|
||||||
|
if (record.equals("MS C")) {
|
||||||
|
return "windows";
|
||||||
|
}
|
||||||
|
if (record.startsWith("Watcom")) {
|
||||||
|
return "watcom";
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +162,7 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||||||
message = "Unable to process relocation at " + addr + " with type 0x" +
|
message = "Unable to process relocation at " + addr + " with type 0x" +
|
||||||
Integer.toHexString(type);
|
Integer.toHexString(type);
|
||||||
program.getBookmarkManager()
|
program.getBookmarkManager()
|
||||||
.setBookmark(addr, BookmarkType.ERROR, "Relocations", message);
|
.setBookmark(addr, BookmarkType.ERROR, "Relocations", message);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message = "Badly broken relocation";
|
message = "Badly broken relocation";
|
||||||
@@ -238,10 +244,9 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||||||
targetAddr += subrec.getTargetDisplacement();
|
targetAddr += subrec.getTargetDisplacement();
|
||||||
locationType = subrec.getLocationType();
|
locationType = subrec.getLocationType();
|
||||||
OmfSegmentHeader seg =
|
OmfSegmentHeader seg =
|
||||||
header.resolveSegment(fixup.getDataBlock().getSegmentIndex());
|
header.resolveSegment(fixup.getDataBlock().getSegmentIndex());
|
||||||
locAddress = seg.getAddress(language)
|
locAddress = seg.getAddress(language)
|
||||||
.add(
|
.add(fixup.getDataBlock().getDataOffset() +
|
||||||
fixup.getDataBlock().getDataOffset() +
|
|
||||||
subrec.getDataRecordOffset());
|
subrec.getDataRecordOffset());
|
||||||
if (locAddress == null) {
|
if (locAddress == null) {
|
||||||
log.appendMsg("Couldn't find address for fixup");
|
log.appendMsg("Couldn't find address for fixup");
|
||||||
@@ -249,74 +254,74 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||||||
}
|
}
|
||||||
finalvalue = targetAddr;
|
finalvalue = targetAddr;
|
||||||
switch (locationType) {
|
switch (locationType) {
|
||||||
case 0: // Low-order byte
|
case 0: // Low-order byte
|
||||||
origbytes = new byte[1];
|
origbytes = new byte[1];
|
||||||
memory.getBytes(locAddress, origbytes);
|
memory.getBytes(locAddress, origbytes);
|
||||||
if (subrec.isSegmentRelative()) {
|
if (subrec.isSegmentRelative()) {
|
||||||
finalvalue += origbytes[0];
|
finalvalue += origbytes[0];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
finalvalue -= (locAddress.getOffset() + 1);
|
finalvalue -= (locAddress.getOffset() + 1);
|
||||||
}
|
}
|
||||||
memory.setByte(locAddress, (byte) finalvalue);
|
memory.setByte(locAddress, (byte) finalvalue);
|
||||||
break;
|
break;
|
||||||
case 1: // 16-bit offset
|
case 1: // 16-bit offset
|
||||||
case 5: // 16-bit loader-resolved offset (treated same as 1)
|
case 5: // 16-bit loader-resolved offset (treated same as 1)
|
||||||
origbytes = new byte[2];
|
origbytes = new byte[2];
|
||||||
memory.getBytes(locAddress, origbytes);
|
memory.getBytes(locAddress, origbytes);
|
||||||
if (subrec.isSegmentRelative()) {
|
if (subrec.isSegmentRelative()) {
|
||||||
finalvalue += converter.getShort(origbytes);
|
finalvalue += converter.getShort(origbytes);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
finalvalue -= (locAddress.getOffset() + 2);
|
finalvalue -= (locAddress.getOffset() + 2);
|
||||||
}
|
}
|
||||||
memory.setShort(locAddress, (short) finalvalue);
|
memory.setShort(locAddress, (short) finalvalue);
|
||||||
break;
|
break;
|
||||||
case 2: // 16-bit base -- logical segment base (selector)
|
case 2: // 16-bit base -- logical segment base (selector)
|
||||||
if (!subrec.isSegmentRelative()) {
|
if (!subrec.isSegmentRelative()) {
|
||||||
// Segment can't be self relative
|
// Segment can't be self relative
|
||||||
relocationError(program, log, locAddress, locationType);
|
relocationError(program, log, locAddress, locationType);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
origbytes = new byte[2];
|
origbytes = new byte[2];
|
||||||
memory.getBytes(locAddress, origbytes);
|
memory.getBytes(locAddress, origbytes);
|
||||||
finalvalue += converter.getShort(origbytes) << 4;
|
finalvalue += converter.getShort(origbytes) << 4;
|
||||||
finalvalue >>= 4; // Convert address to segment
|
finalvalue >>= 4; // Convert address to segment
|
||||||
memory.setShort(locAddress, (short) finalvalue);
|
memory.setShort(locAddress, (short) finalvalue);
|
||||||
break;
|
break;
|
||||||
case 3: // 32-bit far pointer (16-bit segment:16-bit offset)
|
case 3: // 32-bit far pointer (16-bit segment:16-bit offset)
|
||||||
if (!subrec.isSegmentRelative()) {
|
if (!subrec.isSegmentRelative()) {
|
||||||
// Far can't be self relative
|
// Far can't be self relative
|
||||||
relocationError(program, log, locAddress, locationType);
|
relocationError(program, log, locAddress, locationType);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
origbytes = new byte[4];
|
origbytes = new byte[4];
|
||||||
memory.getBytes(locAddress, origbytes);
|
memory.getBytes(locAddress, origbytes);
|
||||||
finalvalue += converter.getInt(origbytes);
|
|
||||||
// Convert to segment:offset in 64K blocks
|
|
||||||
finalvalue =
|
|
||||||
((finalvalue & 0xffff0000L) << 12) | (finalvalue & 0xffff);
|
|
||||||
memory.setInt(locAddress, (int) finalvalue);
|
|
||||||
break;
|
|
||||||
// case 11: // 48-bit far pointer (16-bit segment:32-bit offset)
|
|
||||||
case 4: // High-order byte (high byte of 16-bit offset)
|
|
||||||
case 9: // 32-bit offset
|
|
||||||
case 13: // 32-bit loader-resolved offset (treated same as 9)
|
|
||||||
origbytes = new byte[4];
|
|
||||||
memory.getBytes(locAddress, origbytes);
|
|
||||||
if (subrec.isSegmentRelative()) {
|
|
||||||
finalvalue += converter.getInt(origbytes);
|
finalvalue += converter.getInt(origbytes);
|
||||||
}
|
// Convert to segment:offset in 64K blocks
|
||||||
else {
|
finalvalue =
|
||||||
finalvalue -= (locAddress.getOffset() + 4);
|
((finalvalue & 0xffff0000L) << 12) | (finalvalue & 0xffff);
|
||||||
}
|
memory.setInt(locAddress, (int) finalvalue);
|
||||||
memory.setInt(locAddress, (int) finalvalue);
|
break;
|
||||||
break;
|
// case 11: // 48-bit far pointer (16-bit segment:32-bit offset)
|
||||||
default:
|
case 4: // High-order byte (high byte of 16-bit offset)
|
||||||
log.appendMsg("Unsupported relocation type " +
|
case 9: // 32-bit offset
|
||||||
Integer.toString(locationType) + " at 0x" +
|
case 13: // 32-bit loader-resolved offset (treated same as 9)
|
||||||
Long.toHexString(locAddress.getOffset()));
|
origbytes = new byte[4];
|
||||||
break;
|
memory.getBytes(locAddress, origbytes);
|
||||||
|
if (subrec.isSegmentRelative()) {
|
||||||
|
finalvalue += converter.getInt(origbytes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
finalvalue -= (locAddress.getOffset() + 4);
|
||||||
|
}
|
||||||
|
memory.setInt(locAddress, (int) finalvalue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.appendMsg("Unsupported relocation type " +
|
||||||
|
Integer.toString(locationType) + " at 0x" +
|
||||||
|
Long.toHexString(locAddress.getOffset()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MemoryAccessException e) {
|
catch (MemoryAccessException e) {
|
||||||
@@ -334,7 +339,7 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||||||
long[] values = new long[1];
|
long[] values = new long[1];
|
||||||
values[0] = finalvalue;
|
values[0] = finalvalue;
|
||||||
program.getRelocationTable()
|
program.getRelocationTable()
|
||||||
.add(locAddress, Status.APPLIED, locationType, values, origbytes, null);
|
.add(locAddress, Status.APPLIED, locationType, values, origbytes, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,7 +376,7 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||||||
if (segmentSize == 0) {
|
if (segmentSize == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segment.hasNonZeroData()) {
|
if (segment.hasNonZeroData()) {
|
||||||
MemoryBlockUtils.createInitializedBlock(program, false, segment.getName(),
|
MemoryBlockUtils.createInitializedBlock(program, false, segment.getName(),
|
||||||
segmentAddr, segment.getRawDataStream(reader, log), segmentSize, "", "",
|
segmentAddr, segment.getRawDataStream(reader, log), segmentSize, "", "",
|
||||||
@@ -548,7 +553,8 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||||||
Map<String, OmfSymbol> publicSymbols = header.getPublicSymbols()
|
Map<String, OmfSymbol> publicSymbols = header.getPublicSymbols()
|
||||||
.stream()
|
.stream()
|
||||||
.flatMap(symbolRec -> symbolRec.getSymbols().stream())
|
.flatMap(symbolRec -> symbolRec.getSymbols().stream())
|
||||||
.collect(Collectors.toMap(sym -> sym.getName(), java.util.function.Function.identity()));
|
.collect(
|
||||||
|
Collectors.toMap(sym -> sym.getName(), java.util.function.Function.identity()));
|
||||||
|
|
||||||
monitor.setMessage("Creating External Symbols");
|
monitor.setMessage("Creating External Symbols");
|
||||||
|
|
||||||
|
|||||||
@@ -65,17 +65,17 @@
|
|||||||
</constraint>
|
</constraint>
|
||||||
<constraint loader="Relocatable Object Module Format (OMF)">
|
<constraint loader="Relocatable Object Module Format (OMF)">
|
||||||
<constraint compilerSpecID="windows">
|
<constraint compilerSpecID="windows">
|
||||||
<constraint primary="i386" processor="x86" endian="little" size="32" />
|
<constraint primary="32bit" processor="x86" endian="little" size="32" />
|
||||||
</constraint>
|
</constraint>
|
||||||
<constraint compilerSpecID="default">
|
<constraint compilerSpecID="default">
|
||||||
<constraint primary="i386" processor="x86" endian="little" size="16" />
|
<constraint primary="16bit" processor="x86" endian="little" size="16" />
|
||||||
</constraint>
|
</constraint>
|
||||||
<constraint compilerSpecID="borlandcpp">
|
<constraint compilerSpecID="borlandcpp">
|
||||||
<constraint primary="i386" secondary="borlandcpp" processor="x86" endian="little" size="32" />
|
<constraint primary="32bit" secondary="borlandcpp" processor="x86" endian="little" size="32" />
|
||||||
<constraint primary="i386" secondary="codegearcpp" processor="x86" endian="little" size="32" />
|
<constraint primary="32bit" secondary="codegearcpp" processor="x86" endian="little" size="32" />
|
||||||
</constraint>
|
</constraint>
|
||||||
<constraint compilerSpecID="borlanddelphi">
|
<constraint compilerSpecID="borlanddelphi">
|
||||||
<constraint primary="i386" secondary="borlanddelphi" processor="x86" endian="little" size="32" />
|
<constraint primary="32bit" secondary="borlanddelphi" processor="x86" endian="little" size="32" />
|
||||||
</constraint>
|
</constraint>
|
||||||
</constraint>
|
</constraint>
|
||||||
</opinions>
|
</opinions>
|
||||||
|
|||||||
Reference in New Issue
Block a user