mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge branch 'GP-2997_ryanmkurtz_PR-4857_Gravelbones_omf_alias'
(Closes #4856, Closes #4857)
This commit is contained in:
commit
1a36ad806e
20 changed files with 714 additions and 556 deletions
|
@ -22,17 +22,17 @@ import ghidra.app.util.bin.BinaryReader;
|
|||
|
||||
public class OmfComdefRecord extends OmfExternalSymbol {
|
||||
|
||||
public OmfComdefRecord(BinaryReader reader,boolean isStatic) throws IOException, OmfException {
|
||||
public OmfComdefRecord(BinaryReader reader, boolean isStatic) throws IOException, OmfException {
|
||||
super(isStatic);
|
||||
readRecordHeader(reader);
|
||||
long max = reader.getPointerIndex() + getRecordLength() - 1;
|
||||
|
||||
ArrayList<OmfSymbol> symbollist = new ArrayList<OmfSymbol>();
|
||||
while(reader.getPointerIndex() < max) {
|
||||
while (reader.getPointerIndex() < max) {
|
||||
String name = OmfRecord.readString(reader);
|
||||
int typeIndex = OmfRecord.readIndex(reader);
|
||||
byte dataType = reader.readNextByte();
|
||||
int byteLength=0;
|
||||
int byteLength = 0;
|
||||
if (dataType == 0x61) { // FAR data, reads numElements and elSize
|
||||
int numElements = readCommunalLength(reader);
|
||||
int elSize = readCommunalLength(reader);
|
||||
|
@ -42,7 +42,7 @@ public class OmfComdefRecord extends OmfExternalSymbol {
|
|||
// Values 1 thru 5f plus 61, read the byte length
|
||||
byteLength = readCommunalLength(reader);
|
||||
}
|
||||
OmfSymbol sym = new OmfSymbol(name,typeIndex,0,dataType,byteLength);
|
||||
OmfSymbol sym = new OmfSymbol(name, typeIndex, 0, dataType, byteLength);
|
||||
symbollist.add(sym);
|
||||
}
|
||||
readCheckSumByte(reader);
|
||||
|
@ -52,8 +52,9 @@ public class OmfComdefRecord extends OmfExternalSymbol {
|
|||
|
||||
private static int readCommunalLength(BinaryReader reader) throws OmfException, IOException {
|
||||
int val = reader.readNextByte() & 0xff;
|
||||
if (val <= 128)
|
||||
if (val <= 128) {
|
||||
return val;
|
||||
}
|
||||
if (val == 0x81) {
|
||||
val = reader.readNextShort() & 0xffff;
|
||||
}
|
||||
|
@ -65,8 +66,9 @@ public class OmfComdefRecord extends OmfExternalSymbol {
|
|||
else if (val == 0x88) {
|
||||
val = reader.readNextInt();
|
||||
}
|
||||
else
|
||||
else {
|
||||
throw new OmfException("Illegal communal length encoding");
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,10 @@ public class OmfCommentRecord extends OmfRecord {
|
|||
readCheckSumByte(reader);
|
||||
}
|
||||
|
||||
public byte getCommentType() {
|
||||
return commentType;
|
||||
}
|
||||
|
||||
public byte getCommentClass() {
|
||||
return commentClass;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class OmfEnumeratedData extends OmfRecord implements OmfData {
|
|||
segmentIndex = OmfRecord.readIndex(reader);
|
||||
dataOffset = OmfRecord.readInt2Or4(reader, hasBigFields()) & 0xffffffffL;
|
||||
streamOffset = reader.getPointerIndex();
|
||||
streamLength = getRecordLength() - 1 - (int)(streamOffset - start);
|
||||
streamLength = getRecordLength() - 1 - (int) (streamOffset - start);
|
||||
reader.setPointerIndex(streamOffset + streamLength); // Skip over the data when reading header
|
||||
readCheckSumByte(reader);
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
*/
|
||||
package ghidra.app.util.bin.format.omf;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
|
||||
public class OmfExternalSymbol extends OmfRecord {
|
||||
private boolean isStatic;
|
||||
protected OmfSymbol[] symbol;
|
||||
|
@ -28,16 +28,16 @@ public class OmfExternalSymbol extends OmfRecord {
|
|||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
public OmfExternalSymbol(BinaryReader reader,boolean isStatic) throws IOException {
|
||||
public OmfExternalSymbol(BinaryReader reader, boolean isStatic) throws IOException {
|
||||
this.isStatic = isStatic;
|
||||
readRecordHeader(reader);
|
||||
long max = reader.getPointerIndex() + getRecordLength() - 1;
|
||||
ArrayList<OmfSymbol> symbollist = new ArrayList<OmfSymbol>();
|
||||
|
||||
while(reader.getPointerIndex() < max) {
|
||||
while (reader.getPointerIndex() < max) {
|
||||
String name = OmfRecord.readString(reader);
|
||||
int type = OmfRecord.readIndex(reader);
|
||||
OmfSymbol subrec = new OmfSymbol(name,type,0,0,0);
|
||||
OmfSymbol subrec = new OmfSymbol(name, type, 0, 0, 0);
|
||||
symbollist.add(subrec);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,19 +15,19 @@
|
|||
*/
|
||||
package ghidra.app.util.bin.format.omf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class OmfFileHeader extends OmfRecord {
|
||||
|
||||
private String objectName; // Name of the object module
|
||||
private String libModuleName=null; // Name of the module (within a library)
|
||||
private String translator=null; // Usually the compiler/linker used to produce this object
|
||||
private String libModuleName = null; // Name of the module (within a library)
|
||||
private String translator = null; // Usually the compiler/linker used to produce this object
|
||||
private boolean isLittleEndian;
|
||||
private ArrayList<String> nameList = new ArrayList<String>(); // Indexable List of segment, group, ... names
|
||||
private ArrayList<OmfSegmentHeader> segments = new ArrayList<OmfSegmentHeader>();
|
||||
|
@ -36,7 +36,7 @@ public class OmfFileHeader extends OmfRecord {
|
|||
private ArrayList<OmfSymbolRecord> symbols = new ArrayList<OmfSymbolRecord>();
|
||||
private ArrayList<OmfFixupRecord> fixup = new ArrayList<OmfFixupRecord>();
|
||||
private ArrayList<OmfSegmentHeader> extraSeg = null; // Holds implied segments that don't have official header record
|
||||
// private OmfModuleEnd endModule = null;
|
||||
// private OmfModuleEnd endModule = null;
|
||||
|
||||
public OmfFileHeader(BinaryReader reader) throws IOException {
|
||||
readRecordHeader(reader);
|
||||
|
@ -131,11 +131,11 @@ public class OmfFileHeader extends OmfRecord {
|
|||
*/
|
||||
public void sortSegmentDataBlocks() {
|
||||
if (extraSeg != null) {
|
||||
for(int i=0;i<extraSeg.size();++i) {
|
||||
for (int i = 0; i < extraSeg.size(); ++i) {
|
||||
segments.add(extraSeg.get(i));
|
||||
}
|
||||
}
|
||||
for(int i=0;i<segments.size();++i) {
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
segments.get(i).sortData();
|
||||
}
|
||||
}
|
||||
|
@ -149,16 +149,16 @@ public class OmfFileHeader extends OmfRecord {
|
|||
int index = datablock.getSegmentIndex();
|
||||
int subindex = -1;
|
||||
OmfSegmentHeader segment;
|
||||
if ((index & 0x4000)!=0) {
|
||||
if ((index & 0x4000) != 0) {
|
||||
subindex = index & 0x3fff;
|
||||
index = 1;
|
||||
segment = createOrFindBorlandSegment(subindex, 1);
|
||||
}
|
||||
else {
|
||||
if ((index <=0)||(index>segments.size())) {
|
||||
if ((index <= 0) || (index > segments.size())) {
|
||||
throw new OmfException("Bad segment index");
|
||||
}
|
||||
segment = segments.get(index-1);
|
||||
segment = segments.get(index - 1);
|
||||
}
|
||||
if (subindex != -1) {
|
||||
segment.appendEnumeratedData(datablock);
|
||||
|
@ -179,18 +179,18 @@ public class OmfFileHeader extends OmfRecord {
|
|||
public OmfSegmentHeader resolveSegment(int index) throws OmfException {
|
||||
int subindex = -1;
|
||||
OmfSegmentHeader res;
|
||||
if ((index & 0x4000)!=0) {
|
||||
if ((index & 0x4000) != 0) {
|
||||
subindex = index & 0x3fff;
|
||||
if ((subindex<=0)||(subindex>extraSeg.size())) {
|
||||
if ((subindex <= 0) || (subindex > extraSeg.size())) {
|
||||
throw new OmfException("Bad extra segment index");
|
||||
}
|
||||
res = extraSeg.get(subindex - 1);
|
||||
return res;
|
||||
}
|
||||
if ((index <=0)||(index>segments.size())) {
|
||||
if ((index <= 0) || (index > segments.size())) {
|
||||
throw new OmfException("Bad segment index");
|
||||
}
|
||||
res = segments.get(index-1);
|
||||
res = segments.get(index - 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -201,11 +201,11 @@ public class OmfFileHeader extends OmfRecord {
|
|||
* @throws OmfException if any name indices are malformed
|
||||
*/
|
||||
public void resolveNames() throws OmfException {
|
||||
for(int i=0;i<segments.size();++i) {
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
segments.get(i).resolveNames(nameList);
|
||||
}
|
||||
// extraSeg segments already have names
|
||||
for(int i=0;i<groups.size();++i) {
|
||||
for (int i = 0; i < groups.size(); ++i) {
|
||||
groups.get(i).resolveNames(nameList);
|
||||
}
|
||||
}
|
||||
|
@ -219,17 +219,17 @@ public class OmfFileHeader extends OmfRecord {
|
|||
* @param datatype is the type of (new) segment
|
||||
* @return the corresponding OmfSegmentHeader
|
||||
*/
|
||||
private OmfSegmentHeader createOrFindBorlandSegment(int index,int datatype) {
|
||||
private OmfSegmentHeader createOrFindBorlandSegment(int index, int datatype) {
|
||||
if (extraSeg == null) {
|
||||
extraSeg = new ArrayList<OmfSegmentHeader>();
|
||||
}
|
||||
while(extraSeg.size() < index) {
|
||||
while (extraSeg.size() < index) {
|
||||
extraSeg.add(null);
|
||||
}
|
||||
OmfSegmentHeader segment = extraSeg.get(index-1);
|
||||
OmfSegmentHeader segment = extraSeg.get(index - 1);
|
||||
if (segment == null) {
|
||||
segment = new OmfSegmentHeader(index,datatype);
|
||||
extraSeg.set(index-1,segment);
|
||||
segment = new OmfSegmentHeader(index, datatype);
|
||||
extraSeg.set(index - 1, segment);
|
||||
}
|
||||
return segment;
|
||||
}
|
||||
|
@ -238,9 +238,9 @@ public class OmfFileHeader extends OmfRecord {
|
|||
OmfSymbol[] coms = comdef.getSymbols();
|
||||
for (OmfSymbol sym : coms) {
|
||||
int dt = sym.getDataType();
|
||||
if (dt >0 && dt < 0x60) { // A special borland segment symbol
|
||||
int count = (extraSeg==null) ? 1 : extraSeg.size()+1;
|
||||
createOrFindBorlandSegment(count,dt);
|
||||
if (dt > 0 && dt < 0x60) { // A special borland segment symbol
|
||||
int count = (extraSeg == null) ? 1 : extraSeg.size() + 1;
|
||||
createOrFindBorlandSegment(count, dt);
|
||||
sym.setSegmentRef(count);
|
||||
|
||||
}
|
||||
|
@ -256,36 +256,35 @@ public class OmfFileHeader extends OmfRecord {
|
|||
* @throws IOException for problems reading program data
|
||||
* @throws OmfException for malformed records
|
||||
*/
|
||||
public static OmfFileHeader scan(BinaryReader reader,TaskMonitor monitor,boolean initialCommentsOnly) throws IOException, OmfException {
|
||||
public static OmfFileHeader scan(BinaryReader reader, TaskMonitor monitor,
|
||||
boolean initialCommentsOnly) throws IOException, OmfException {
|
||||
OmfRecord record = OmfRecord.readRecord(reader);
|
||||
if ((record.getRecordType() & (byte)0xfc)!=OmfRecord.THEADR) {
|
||||
if (!(record instanceof OmfFileHeader)) {
|
||||
throw new OmfException("Object file does not start with proper header");
|
||||
}
|
||||
OmfFileHeader header = (OmfFileHeader)record;
|
||||
byte type = record.getRecordType();
|
||||
type &= 0xfe;
|
||||
while(type != MODEND) {
|
||||
if (monitor.isCancelled()) {
|
||||
break; // Return what we have
|
||||
}
|
||||
OmfFileHeader header = (OmfFileHeader) record;
|
||||
|
||||
while (true) {
|
||||
record = OmfRecord.readRecord(reader);
|
||||
type = record.getRecordType();
|
||||
type &= 0xfe; // Mask off the least significant bit
|
||||
if (initialCommentsOnly && (type != COMENT)) {
|
||||
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
switch(type) {
|
||||
case COMENT:
|
||||
byte commentClass = ((OmfCommentRecord)record).getCommentClass();
|
||||
if (record instanceof OmfModuleEnd) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (record instanceof OmfCommentRecord comment) {
|
||||
byte commentClass = comment.getCommentClass();
|
||||
if (commentClass == OmfCommentRecord.COMMENT_CLASS_TRANSLATOR) {
|
||||
header.translator = ((OmfCommentRecord)record).getValue();
|
||||
header.translator = comment.getValue();
|
||||
}
|
||||
else if (commentClass == OmfCommentRecord.COMMENT_CLASS_LIBMOD) {
|
||||
header.libModuleName = ((OmfCommentRecord)record).getValue();
|
||||
header.libModuleName = comment.getValue();
|
||||
}
|
||||
}
|
||||
else if (initialCommentsOnly) {
|
||||
break;
|
||||
default:
|
||||
break; // Skip most records
|
||||
}
|
||||
}
|
||||
return header;
|
||||
|
@ -293,86 +292,86 @@ public class OmfFileHeader extends OmfRecord {
|
|||
|
||||
/**
|
||||
* Parse the entire object file
|
||||
*
|
||||
* @param reader is the byte stream
|
||||
* @param monitor is checked for cancel button
|
||||
* @param log the log
|
||||
* @return the header record as root of object
|
||||
* @throws IOException for problems reading data
|
||||
* @throws OmfException for malformed records
|
||||
*/
|
||||
public static OmfFileHeader parse(BinaryReader reader,TaskMonitor monitor) throws IOException, OmfException {
|
||||
public static OmfFileHeader parse(BinaryReader reader, TaskMonitor monitor, MessageLog log)
|
||||
throws IOException, OmfException {
|
||||
OmfRecord record = OmfRecord.readRecord(reader);
|
||||
if ((record.getRecordType() & (byte)0xfc)!=OmfRecord.THEADR) {
|
||||
if (!(record instanceof OmfFileHeader)) {
|
||||
throw new OmfException("Object file does not start with proper header");
|
||||
}
|
||||
OmfFileHeader header = (OmfFileHeader)record;
|
||||
OmfFileHeader header = (OmfFileHeader) record;
|
||||
Object lastDataBlock = null;
|
||||
|
||||
while((record.getRecordType() & (byte)0xfe) != OmfRecord.MODEND) {
|
||||
if (monitor.isCancelled()) {
|
||||
break; // Return what we have
|
||||
}
|
||||
while (true) {
|
||||
record = OmfRecord.readRecord(reader);
|
||||
byte type = record.getRecordType();
|
||||
type &= 0xfe; // Mask off the least significant bit
|
||||
switch(type) {
|
||||
case COMENT:
|
||||
byte commentClass = ((OmfCommentRecord)record).getCommentClass();
|
||||
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
if (record instanceof OmfModuleEnd) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (record instanceof OmfCommentRecord comment) {
|
||||
byte commentClass = comment.getCommentClass();
|
||||
if (commentClass == OmfCommentRecord.COMMENT_CLASS_TRANSLATOR) {
|
||||
header.translator = ((OmfCommentRecord)record).getValue();
|
||||
header.translator = comment.getValue();
|
||||
}
|
||||
else if (commentClass == OmfCommentRecord.COMMENT_CLASS_LIBMOD) {
|
||||
header.libModuleName = ((OmfCommentRecord)record).getValue();
|
||||
header.libModuleName = comment.getValue();
|
||||
}
|
||||
break;
|
||||
case MODEND:
|
||||
// header.endModule = (OmfModuleEnd)record;
|
||||
// We are not currently examining the end module record
|
||||
break;
|
||||
case COMDEF:
|
||||
case LCOMDEF:
|
||||
header.evaluateComdef((OmfComdefRecord)record);
|
||||
header.externsymbols.add((OmfExternalSymbol)record);
|
||||
break;
|
||||
case LEXTDEF:
|
||||
case EXTDEF:
|
||||
header.externsymbols.add((OmfExternalSymbol)record);
|
||||
break;
|
||||
case PUBDEF:
|
||||
case LPUBDEF:
|
||||
header.symbols.add((OmfSymbolRecord)record);
|
||||
break;
|
||||
case LINNUM:
|
||||
break; // Not saving this information currently
|
||||
case LNAMES:
|
||||
((OmfNamesRecord)record).appendNames(header.nameList); // Keep names, otherwise don't save record
|
||||
break;
|
||||
case SEGDEF:
|
||||
header.segments.add((OmfSegmentHeader)record);
|
||||
break;
|
||||
case GRPDEF:
|
||||
header.groups.add((OmfGroupRecord)record);
|
||||
break;
|
||||
case FIXUPP:
|
||||
OmfFixupRecord fixuprec = (OmfFixupRecord)record;
|
||||
}
|
||||
else if (record instanceof OmfComdefRecord comdef) {
|
||||
header.evaluateComdef(comdef);
|
||||
header.externsymbols.add((OmfExternalSymbol) record);
|
||||
}
|
||||
else if (record instanceof OmfExternalSymbol external) {
|
||||
header.externsymbols.add(external);
|
||||
}
|
||||
else if (record instanceof OmfSymbolRecord symbol) {
|
||||
header.symbols.add(symbol);
|
||||
}
|
||||
else if (record instanceof OmfNamesRecord names) {
|
||||
names.appendNames(header.nameList); // Keep names, otherwise don't save record
|
||||
}
|
||||
else if (record instanceof OmfSegmentHeader seghead) {
|
||||
header.segments.add(seghead);
|
||||
}
|
||||
else if (record instanceof OmfGroupRecord group) {
|
||||
header.groups.add(group);
|
||||
}
|
||||
else if (record instanceof OmfFixupRecord fixuprec) {
|
||||
fixuprec.setDataBlock(lastDataBlock);
|
||||
header.fixup.add(fixuprec);
|
||||
break;
|
||||
case LEDATA:
|
||||
OmfEnumeratedData enumheader = (OmfEnumeratedData)record;
|
||||
}
|
||||
else if (record instanceof OmfEnumeratedData enumheader) {
|
||||
header.addEnumeratedBlock(enumheader);
|
||||
lastDataBlock = enumheader;
|
||||
break;
|
||||
case LIDATA:
|
||||
OmfIteratedData iterheader = (OmfIteratedData)record;
|
||||
if (iterheader.getSegmentIndex() <= 0 || iterheader.getSegmentIndex() > header.segments.size()) {
|
||||
}
|
||||
else if (record instanceof OmfIteratedData iterheader) {
|
||||
if (iterheader.getSegmentIndex() <= 0 ||
|
||||
iterheader.getSegmentIndex() > header.segments.size()) {
|
||||
throw new OmfException("Bad segment index on LIDATA");
|
||||
}
|
||||
OmfSegmentHeader segheader2 = header.segments.get(iterheader.getSegmentIndex()-1);
|
||||
OmfSegmentHeader segheader2 = header.segments.get(iterheader.getSegmentIndex() - 1);
|
||||
segheader2.addIteratedData(iterheader);
|
||||
lastDataBlock = iterheader;
|
||||
break;
|
||||
default:
|
||||
// Should never reach here
|
||||
}
|
||||
else if (record instanceof OmfUnsupportedRecord) {
|
||||
logRecord("Unsupported OMF record", record, log);
|
||||
}
|
||||
else if (record instanceof OmfObsoleteRecord) {
|
||||
logRecord("Obsolete OMF record", record, log);
|
||||
}
|
||||
else if (record instanceof OmfUnknownRecord) {
|
||||
logRecord("Unknown OMF record", record, log);
|
||||
}
|
||||
}
|
||||
return header;
|
||||
|
@ -386,7 +385,8 @@ public class OmfFileHeader extends OmfRecord {
|
|||
* @param groups is the list of specific segments that are grouped together in memory
|
||||
* @throws OmfException for malformed index/alignment/combining fields
|
||||
*/
|
||||
public static void doLinking(long startAddress,ArrayList<OmfSegmentHeader> segments,ArrayList<OmfGroupRecord> groups) throws OmfException {
|
||||
public static void doLinking(long startAddress, ArrayList<OmfSegmentHeader> segments,
|
||||
ArrayList<OmfGroupRecord> groups) throws OmfException {
|
||||
// Link anything in groups first
|
||||
for (int i = 0; i < groups.size(); ++i) {
|
||||
OmfGroupRecord group = groups.get(i);
|
||||
|
@ -396,14 +396,15 @@ public class OmfFileHeader extends OmfRecord {
|
|||
try {
|
||||
OmfSegmentHeader segment = segments.get(index - 1);
|
||||
startAddress = segment.relocateSegment(startAddress, -1);
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
}
|
||||
catch (IndexOutOfBoundsException ex) {
|
||||
throw new OmfException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in any remaining segments
|
||||
for(int i=0;i<segments.size();++i) {
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
OmfSegmentHeader segment = segments.get(i);
|
||||
if (segment.getStartAddress() != -1) {
|
||||
continue; // Address already assigned
|
||||
|
@ -411,7 +412,7 @@ public class OmfFileHeader extends OmfRecord {
|
|||
|
||||
startAddress = segment.relocateSegment(startAddress, -1);
|
||||
// Look for any segments with same name,class which should be officially "combined" with this segment
|
||||
for(int j=i+1;j<segments.size();++j) {
|
||||
for (int j = i + 1; j < segments.size(); ++j) {
|
||||
OmfSegmentHeader combineSeg = segments.get(j);
|
||||
if (combineSeg.getStartAddress() != -1) {
|
||||
continue;
|
||||
|
@ -426,10 +427,10 @@ public class OmfFileHeader extends OmfRecord {
|
|||
if (C == 0) {
|
||||
continue; // Private segment
|
||||
}
|
||||
if (C==2 || C==4 || C==7) {
|
||||
if (C == 2 || C == 4 || C == 7) {
|
||||
startAddress = combineSeg.relocateSegment(startAddress, -1);
|
||||
}
|
||||
else if (C==5) {
|
||||
else if (C == 5) {
|
||||
startAddress = combineSeg.relocateSegment(startAddress, 1);
|
||||
}
|
||||
else {
|
||||
|
@ -464,6 +465,10 @@ public class OmfFileHeader extends OmfRecord {
|
|||
* @return the new reader
|
||||
*/
|
||||
public static BinaryReader createReader(ByteProvider provider) {
|
||||
return new BinaryReader(provider,true/* Always little endian */);
|
||||
return new BinaryReader(provider, true/* Always little endian */);
|
||||
}
|
||||
|
||||
private static void logRecord(String description, OmfRecord record, MessageLog log) {
|
||||
log.appendMsg(description + " (" + record + ")");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,13 +30,13 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
|
||||
public OmfFixupRecord(BinaryReader reader) throws IOException {
|
||||
ArrayList<Subrecord> subreclist = new ArrayList<Subrecord>();
|
||||
boolean hasBigFields = ((getRecordType() & 1)!=0);
|
||||
boolean hasBigFields = ((getRecordType() & 1) != 0);
|
||||
|
||||
readRecordHeader(reader);
|
||||
long max = reader.getPointerIndex() + getRecordLength() - 1;
|
||||
while(reader.getPointerIndex() < max) {
|
||||
while (reader.getPointerIndex() < max) {
|
||||
byte peek = reader.peekNextByte();
|
||||
if ((peek & 0x80)==0) {
|
||||
if ((peek & 0x80) == 0) {
|
||||
ThreadSubrecord subrec = ThreadSubrecord.readThreadSubrecord(reader, hasBigFields);
|
||||
subreclist.add(subrec);
|
||||
}
|
||||
|
@ -52,11 +52,11 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
|
||||
public void setDataBlock(Object last) {
|
||||
if (last instanceof OmfEnumeratedData) {
|
||||
lastLEData = (OmfEnumeratedData)last;
|
||||
lastLEData = (OmfEnumeratedData) last;
|
||||
lastLIData = null;
|
||||
}
|
||||
else {
|
||||
lastLIData = (OmfIteratedData)last;
|
||||
lastLIData = (OmfIteratedData) last;
|
||||
lastLEData = null;
|
||||
}
|
||||
}
|
||||
|
@ -79,8 +79,8 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
public boolean M; // true for segment-relative, false for self-relative
|
||||
public int locationType;
|
||||
|
||||
public FixupState(OmfFileHeader header,ArrayList<OmfSymbol> externsyms,Language lang) {
|
||||
for(int i=0;i<4;++i) {
|
||||
public FixupState(OmfFileHeader header, ArrayList<OmfSymbol> externsyms, Language lang) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
frameThreads[i] = null;
|
||||
targetThreads[i] = null;
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
}
|
||||
|
||||
public int getMethod() {
|
||||
return (type>>2) & 7;
|
||||
return (type >> 2) & 7;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
|
@ -126,7 +126,7 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
}
|
||||
|
||||
public boolean isFrameThread() {
|
||||
return ((type>>6)&1)!=0;
|
||||
return ((type >> 6) & 1) != 0;
|
||||
}
|
||||
|
||||
public int getThreadNum() {
|
||||
|
@ -134,20 +134,25 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
}
|
||||
|
||||
public void updateState(FixupState state) {
|
||||
if (isFrameThread())
|
||||
if (isFrameThread()) {
|
||||
state.frameThreads[getThreadNum()] = this;
|
||||
else
|
||||
}
|
||||
else {
|
||||
state.targetThreads[getThreadNum()] = this;
|
||||
}
|
||||
}
|
||||
|
||||
public static ThreadSubrecord readThreadSubrecord(BinaryReader reader,boolean hasBigFields) throws IOException {
|
||||
public static ThreadSubrecord readThreadSubrecord(BinaryReader reader, boolean hasBigFields)
|
||||
throws IOException {
|
||||
ThreadSubrecord thread = new ThreadSubrecord();
|
||||
thread.type = reader.readNextByte();
|
||||
int method = thread.getMethod();
|
||||
if (method < 4)
|
||||
if (method < 4) {
|
||||
thread.index = OmfRecord.readInt1Or2(reader, hasBigFields);
|
||||
else
|
||||
}
|
||||
else {
|
||||
thread.index = -1;
|
||||
}
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
@ -159,19 +164,19 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
private int targetDisplacement;
|
||||
|
||||
public boolean isFrameThread() {
|
||||
return ((fixData>>7)&1)!=0;
|
||||
return ((fixData >> 7) & 1) != 0;
|
||||
}
|
||||
|
||||
public boolean isTargetThread() {
|
||||
return ((fixData>>3)&1)!=0;
|
||||
return ((fixData >> 3) & 1) != 0;
|
||||
}
|
||||
|
||||
public int getFrameMethod() {
|
||||
return ((fixData>>4)&7);
|
||||
return ((fixData >> 4) & 7);
|
||||
}
|
||||
|
||||
public int getP() {
|
||||
int res = (fixData >>2)&1;
|
||||
int res = (fixData >> 2) & 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -180,7 +185,7 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
int index;
|
||||
if (isFrameThread()) {
|
||||
// Frame datum from a thread
|
||||
int threadnum = ((fixData>>4)&3);
|
||||
int threadnum = ((fixData >> 4) & 3);
|
||||
ThreadSubrecord subrec = state.frameThreads[threadnum];
|
||||
method = subrec.getMethod();
|
||||
index = subrec.getIndex();
|
||||
|
@ -189,21 +194,23 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
method = getFrameMethod();
|
||||
index = frameDatum;
|
||||
}
|
||||
switch(method) {
|
||||
switch (method) {
|
||||
case 0: // Index is for a segment
|
||||
state.frameState = state.header.resolveSegment(index).getFrameDatum();
|
||||
break;
|
||||
case 1: // Index is for a group
|
||||
state.frameState = state.groups.get(index-1).getFrameDatum();
|
||||
state.frameState = state.groups.get(index - 1).getFrameDatum();
|
||||
break;
|
||||
case 2: // Index is for an external symbol
|
||||
state.frameState = state.externals.get(index-1).getFrameDatum();
|
||||
state.frameState = state.externals.get(index - 1).getFrameDatum();
|
||||
break;
|
||||
case 4: // Segment Index grabbed from datablock
|
||||
if (state.currentFixupRecord.lastLEData != null)
|
||||
if (state.currentFixupRecord.lastLEData != null) {
|
||||
index = state.currentFixupRecord.lastLEData.getSegmentIndex();
|
||||
else
|
||||
}
|
||||
else {
|
||||
index = state.currentFixupRecord.lastLIData.getSegmentIndex();
|
||||
}
|
||||
state.frameState = state.header.resolveSegment(index).getFrameDatum();
|
||||
break;
|
||||
case 5: // Frame determined by target
|
||||
|
@ -230,17 +237,17 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
index = targetDatum;
|
||||
}
|
||||
|
||||
switch(method) {
|
||||
switch (method) {
|
||||
case 0: // Index is for a segment
|
||||
state.targetState = state.header.resolveSegment(index).getStartAddress();
|
||||
state.targetState += targetDisplacement;
|
||||
break;
|
||||
case 1: // Index is for a group
|
||||
state.targetState = state.groups.get(index-1).getStartAddress();
|
||||
state.targetState = state.groups.get(index - 1).getStartAddress();
|
||||
state.targetState += targetDisplacement;
|
||||
break;
|
||||
case 2: // Index is for an external symbol
|
||||
state.targetState = state.externals.get(index-1).getAddress().getOffset();
|
||||
state.targetState = state.externals.get(index - 1).getAddress().getOffset();
|
||||
state.targetState += targetDisplacement;
|
||||
break;
|
||||
// case 3: // Not supported by many linkers
|
||||
|
@ -248,29 +255,30 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
state.targetState = state.header.resolveSegment(index).getStartAddress();
|
||||
break;
|
||||
case 5: // group only, no displacement
|
||||
state.targetState = state.groups.get(index-1).getStartAddress();
|
||||
state.targetState = state.groups.get(index - 1).getStartAddress();
|
||||
break;
|
||||
case 6: // external only, no displacement
|
||||
state.targetState = state.externals.get(index-1).getAddress().getOffset();
|
||||
state.targetState = state.externals.get(index - 1).getAddress().getOffset();
|
||||
break;
|
||||
default:
|
||||
state.targetState = -1; // This indicates an unresolved target
|
||||
}
|
||||
}
|
||||
|
||||
public static FixupTarget readFixupTarget(BinaryReader reader,boolean hasBigFields) throws IOException {
|
||||
public static FixupTarget readFixupTarget(BinaryReader reader, boolean hasBigFields)
|
||||
throws IOException {
|
||||
FixupTarget fixupTarget = new FixupTarget();
|
||||
fixupTarget.fixData = reader.readNextByte();
|
||||
if ((fixupTarget.fixData & 0x80)==0) { // F=0 (explicit frame method (and datum))
|
||||
int method = (fixupTarget.fixData >> 4)&7;
|
||||
if (method <3) {
|
||||
if ((fixupTarget.fixData & 0x80) == 0) { // F=0 (explicit frame method (and datum))
|
||||
int method = (fixupTarget.fixData >> 4) & 7;
|
||||
if (method < 3) {
|
||||
fixupTarget.frameDatum = OmfRecord.readIndex(reader);
|
||||
}
|
||||
}
|
||||
if ((fixupTarget.fixData & 0x08)==0) { // T=0 (explicit target)
|
||||
if ((fixupTarget.fixData & 0x08) == 0) { // T=0 (explicit target)
|
||||
fixupTarget.targetDatum = OmfRecord.readIndex(reader);
|
||||
}
|
||||
if ((fixupTarget.fixData & 0x04)==0) // P=0
|
||||
if ((fixupTarget.fixData & 0x04) == 0) // P=0
|
||||
fixupTarget.targetDisplacement = OmfRecord.readInt2Or4(reader, hasBigFields);
|
||||
return fixupTarget;
|
||||
}
|
||||
|
@ -289,8 +297,8 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
|
||||
target.resolveTarget(state); // Resolve target first as frame may need to reference results
|
||||
target.resolveFrame(state);
|
||||
state.M = ((lobyte>>6)&1)!=0;
|
||||
state.locationType = ((lobyte>>2)&0xf);
|
||||
state.M = ((lobyte >> 6) & 1) != 0;
|
||||
state.locationType = ((lobyte >> 2) & 0xf);
|
||||
int dataRecordOffset = lobyte & 3;
|
||||
dataRecordOffset <<= 8;
|
||||
dataRecordOffset |= (hibyte) & 0xff;
|
||||
|
@ -308,7 +316,8 @@ public class OmfFixupRecord extends OmfRecord {
|
|||
state.locAddress = seg.getAddress(state.language).add(blockDisplace + dataRecordOffset);
|
||||
}
|
||||
|
||||
public static FixupSubrecord readFixupSubrecord(BinaryReader reader,boolean hasBigFields) throws IOException {
|
||||
public static FixupSubrecord readFixupSubrecord(BinaryReader reader, boolean hasBigFields)
|
||||
throws IOException {
|
||||
FixupSubrecord fixupSubrecord = new FixupSubrecord();
|
||||
fixupSubrecord.lobyte = reader.readNextByte();
|
||||
fixupSubrecord.hibyte = reader.readNextByte();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -35,12 +34,12 @@ public class OmfGroupRecord extends OmfRecord {
|
|||
long max = reader.getPointerIndex() + getRecordLength() - 1;
|
||||
groupNameIndex = OmfRecord.readIndex(reader);
|
||||
ArrayList<GroupSubrecord> grouplist = new ArrayList<GroupSubrecord>();
|
||||
while(reader.getPointerIndex() < max) {
|
||||
while (reader.getPointerIndex() < max) {
|
||||
GroupSubrecord subrec = GroupSubrecord.read(reader);
|
||||
grouplist.add(subrec);
|
||||
}
|
||||
readCheckSumByte(reader);
|
||||
group = new GroupSubrecord[ grouplist.size() ];
|
||||
group = new GroupSubrecord[grouplist.size()];
|
||||
grouplist.toArray(group);
|
||||
}
|
||||
|
||||
|
@ -58,7 +57,7 @@ public class OmfGroupRecord extends OmfRecord {
|
|||
|
||||
/**
|
||||
* This is the segment selector needed for this object
|
||||
* @return
|
||||
* @return The segment selector
|
||||
*/
|
||||
public int getFrameDatum() {
|
||||
return 0; // TODO: Need to fill in a real segment selector
|
||||
|
@ -82,10 +81,12 @@ public class OmfGroupRecord extends OmfRecord {
|
|||
}
|
||||
|
||||
public void resolveNames(ArrayList<String> nameList) throws OmfException {
|
||||
if (groupNameIndex <= 0)
|
||||
if (groupNameIndex <= 0) {
|
||||
throw new OmfException("Cannot have unused group name");
|
||||
if (groupNameIndex > nameList.size())
|
||||
}
|
||||
if (groupNameIndex > nameList.size()) {
|
||||
throw new OmfException("Group name index out of bounds");
|
||||
}
|
||||
groupName = nameList.get(groupNameIndex - 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ public class OmfIteratedData extends OmfRecord implements OmfData {
|
|||
segmentIndex = OmfRecord.readIndex(reader);
|
||||
dataOffset = OmfRecord.readInt2Or4(reader, hasBigFields);
|
||||
ArrayList<DataBlock> blocklist = new ArrayList<DataBlock>();
|
||||
while(reader.getPointerIndex() < max) {
|
||||
while (reader.getPointerIndex() < max) {
|
||||
DataBlock block = DataBlock.read(reader, hasBigFields);
|
||||
blocklist.add(block);
|
||||
}
|
||||
|
@ -100,21 +100,21 @@ public class OmfIteratedData extends OmfRecord implements OmfData {
|
|||
private byte[] simpleBlock = null;
|
||||
private DataBlock[] nestedBlock = null;
|
||||
|
||||
public static DataBlock read(BinaryReader reader,boolean hasBigFields) throws IOException {
|
||||
public static DataBlock read(BinaryReader reader, boolean hasBigFields) throws IOException {
|
||||
DataBlock subblock = new DataBlock();
|
||||
subblock.repeatCount = OmfRecord.readInt2Or4(reader, hasBigFields);
|
||||
subblock.blockCount = reader.readNextShort() & 0xffff;
|
||||
if (subblock.blockCount == 0) {
|
||||
int size = reader.readNextByte() & 0xff;
|
||||
subblock.simpleBlock = new byte[ size ];
|
||||
for(int i=0;i<size;++i) {
|
||||
subblock.simpleBlock = new byte[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
subblock.simpleBlock[i] = reader.readNextByte();
|
||||
}
|
||||
}
|
||||
else {
|
||||
subblock.nestedBlock = new DataBlock[subblock.blockCount];
|
||||
for(int i=0;i<subblock.blockCount;++i) {
|
||||
subblock.nestedBlock[i] = read(reader,hasBigFields); // Recursive definition
|
||||
for (int i = 0; i < subblock.blockCount; ++i) {
|
||||
subblock.nestedBlock[i] = read(reader, hasBigFields); // Recursive definition
|
||||
}
|
||||
}
|
||||
return subblock;
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
*/
|
||||
package ghidra.app.util.bin.format.omf;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class OmfLibraryRecord extends OmfRecord {
|
||||
private int pageSize; // All archive members must start on a page boundary of this size
|
||||
private long dictionaryOffset;
|
||||
|
@ -55,50 +55,63 @@ public class OmfLibraryRecord extends OmfRecord {
|
|||
|
||||
public static boolean checkMagicNumer(BinaryReader reader) throws IOException {
|
||||
byte type = reader.readNextByte();
|
||||
if (type != (byte)0xF0)
|
||||
if (type != (byte) 0xF0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int pageSize = (reader.readNextShort() & 0xffff) + 3;
|
||||
// Make sure page size is a power of 2, 2^4 - 2^15
|
||||
int count = 0;
|
||||
int mask = pageSize;
|
||||
while((mask & 1)==0) {
|
||||
while ((mask & 1) == 0) {
|
||||
count += 1;
|
||||
mask >>>= 1;
|
||||
}
|
||||
if (mask != 1) return false; // Test if this is a power of 2
|
||||
if (count < 4) return false;
|
||||
if (count > 15) return false;
|
||||
if (mask != 1) {
|
||||
return false; // Test if this is a power of 2
|
||||
}
|
||||
if (count < 4) {
|
||||
return false;
|
||||
}
|
||||
if (count > 15) {
|
||||
return false;
|
||||
}
|
||||
reader.align(pageSize);
|
||||
type = reader.readNextByte();
|
||||
if ((type & 0xfc) != 0x80) return false;
|
||||
if ((type & 0xfc) != 0x80) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static OmfLibraryRecord parse(BinaryReader reader,TaskMonitor monitor) throws IOException {
|
||||
public static OmfLibraryRecord parse(BinaryReader reader, TaskMonitor monitor)
|
||||
throws IOException {
|
||||
OmfLibraryRecord res = null;
|
||||
byte type = reader.peekNextByte();
|
||||
if (type != (byte)0xF0)
|
||||
if (type != (byte) 0xF0) {
|
||||
throw new IOException("Not an OMF Library record");
|
||||
}
|
||||
res = new OmfLibraryRecord(reader);
|
||||
res.members = new ArrayList<MemberHeader>();
|
||||
reader.align(res.pageSize); // Skip padding to get to next page boundary
|
||||
type = reader.peekNextByte();
|
||||
while(type != (byte)0xF1) { // Until we see the official "end of library" record
|
||||
while (type != (byte) 0xF1) { // Until we see the official "end of library" record
|
||||
MemberHeader curheader = new MemberHeader();
|
||||
curheader.payloadOffset = reader.getPointerIndex();
|
||||
OmfFileHeader fileheader;
|
||||
try {
|
||||
fileheader = OmfFileHeader.scan(reader, monitor,false);
|
||||
} catch (OmfException e) {
|
||||
fileheader = OmfFileHeader.scan(reader, monitor, false);
|
||||
}
|
||||
catch (OmfException e) {
|
||||
throw new IOException("Could not parse individual object file within archive");
|
||||
}
|
||||
curheader.name = fileheader.getLibraryModuleName(); // (preferred) name of the object module
|
||||
if (curheader.name == null)
|
||||
if (curheader.name == null) {
|
||||
curheader.name = fileheader.getName(); // As a back-up, this is usually the name of the original source
|
||||
}
|
||||
curheader.machineName = fileheader.getMachineName();
|
||||
curheader.translator = fileheader.getTranslator();
|
||||
curheader.size = (int)(reader.getPointerIndex() - curheader.payloadOffset);
|
||||
curheader.size = (int) (reader.getPointerIndex() - curheader.payloadOffset);
|
||||
res.members.add(curheader);
|
||||
reader.align(res.pageSize); // Skip padding to get to next page boundary
|
||||
type = reader.peekNextByte();
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.omf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
|
||||
public class OmfLineNumberRecord extends OmfRecord {
|
||||
private int baseGroup;
|
||||
private int baseSegment;
|
||||
private LineSubrecord[] linenumber;
|
||||
|
||||
public OmfLineNumberRecord(BinaryReader reader) throws IOException {
|
||||
readRecordHeader(reader);
|
||||
boolean hasBigFields = hasBigFields();
|
||||
baseGroup = OmfRecord.readIndex(reader);
|
||||
baseSegment = OmfRecord.readIndex(reader);
|
||||
long max = reader.getPointerIndex() + getRecordLength() - 1;
|
||||
ArrayList<LineSubrecord> linelist = new ArrayList<LineSubrecord>();
|
||||
while(reader.getPointerIndex() < max) {
|
||||
LineSubrecord subrec = LineSubrecord.read(reader,hasBigFields);
|
||||
linelist.add(subrec);
|
||||
}
|
||||
readCheckSumByte(reader);
|
||||
linenumber = new LineSubrecord[linelist.size()];
|
||||
linelist.toArray(linenumber);
|
||||
}
|
||||
|
||||
public static class LineSubrecord {
|
||||
private int lineNumber;
|
||||
private int lineNumberOffset;
|
||||
|
||||
public static LineSubrecord read(BinaryReader reader,boolean hasBigFields) throws IOException {
|
||||
LineSubrecord subrec = new LineSubrecord();
|
||||
subrec.lineNumber = reader.readNextShort() & 0xffff;
|
||||
subrec.lineNumberOffset = OmfRecord.readInt2Or4(reader, hasBigFields);
|
||||
return subrec;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -27,16 +26,17 @@ public class OmfModuleEnd extends OmfRecord {
|
|||
public OmfModuleEnd(BinaryReader reader) throws IOException {
|
||||
readRecordHeader(reader);
|
||||
moduleType = reader.readNextByte();
|
||||
if (hasStartAddress())
|
||||
startAddress = OmfFixupRecord.FixupTarget.readFixupTarget(reader,hasBigFields());
|
||||
if (hasStartAddress()) {
|
||||
startAddress = OmfFixupRecord.FixupTarget.readFixupTarget(reader, hasBigFields());
|
||||
}
|
||||
readCheckSumByte(reader);
|
||||
}
|
||||
|
||||
public boolean isMainProgramModule() {
|
||||
return ((moduleType & 0x80)!=0);
|
||||
return ((moduleType & 0x80) != 0);
|
||||
}
|
||||
|
||||
public boolean hasStartAddress() {
|
||||
return ((moduleType & 0x40)!=0);
|
||||
return ((moduleType & 0x40) != 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -26,9 +25,9 @@ public class OmfNamesRecord extends OmfRecord {
|
|||
|
||||
public OmfNamesRecord(BinaryReader reader) throws IOException {
|
||||
readRecordHeader(reader);
|
||||
long max = reader.getPointerIndex() + getRecordLength() -1;
|
||||
long max = reader.getPointerIndex() + getRecordLength() - 1;
|
||||
name = new ArrayList<String>();
|
||||
while(reader.getPointerIndex() < max) {
|
||||
while (reader.getPointerIndex() < max) {
|
||||
String nm = OmfRecord.readString(reader);
|
||||
name.add(nm);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.omf;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
|
||||
public class OmfObsoleteRecord extends OmfRecord {
|
||||
|
||||
/**
|
||||
* Create a new {@link OmfObsoleteRecord}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||
* @throws IOException If an IO-related error occurred
|
||||
*/
|
||||
public OmfObsoleteRecord(BinaryReader reader) throws IOException {
|
||||
readRecordHeader(reader);
|
||||
reader.setPointerIndex(reader.getPointerIndex() + getRecordLength());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,29 +16,61 @@
|
|||
package ghidra.app.util.bin.format.omf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
|
||||
public abstract class OmfRecord {
|
||||
public final static byte THEADR = (byte)0x80;
|
||||
public final static byte LHEADR = (byte)0x82;
|
||||
public final static byte COMENT = (byte)0x88;
|
||||
public final static byte MODEND = (byte)0x8A;
|
||||
public final static byte EXTDEF = (byte)0x8C;
|
||||
public final static byte PUBDEF = (byte)0x90;
|
||||
public final static byte LINNUM = (byte)0x94;
|
||||
public final static byte LNAMES = (byte)0x96;
|
||||
public final static byte SEGDEF = (byte)0x98;
|
||||
public final static byte GRPDEF = (byte)0x9A;
|
||||
public final static byte FIXUPP = (byte)0x9C;
|
||||
public final static byte LEDATA = (byte)0xA0;
|
||||
public final static byte LIDATA = (byte)0xA2;
|
||||
public final static byte COMDEF = (byte)0xB0;
|
||||
public final static byte LEXTDEF = (byte)0xB4;
|
||||
public final static byte LPUBDEF = (byte)0xB6;
|
||||
public final static byte LCOMDEF = (byte)0xB8;
|
||||
public final static byte RHEADR = (byte) 0x6E; // Obsolete
|
||||
public final static byte REGINT = (byte) 0x70; // Obsolete
|
||||
public final static byte REDATA = (byte) 0x72; // Obsolete
|
||||
public final static byte RIDATA = (byte) 0x74; // Obsolete
|
||||
public final static byte OVLDEF = (byte) 0x76; // Obsolete
|
||||
public final static byte ENDREC = (byte) 0x78; // Obsolete
|
||||
public final static byte BLKDEF = (byte) 0x7A; // Obsolete
|
||||
public final static byte BLKEND = (byte) 0x7C; // Obsolete
|
||||
public final static byte DEBSYM = (byte) 0x7E; // Obsolete
|
||||
public final static byte THEADR = (byte) 0x80;
|
||||
public final static byte LHEADR = (byte) 0x82;
|
||||
public final static byte PEDATA = (byte) 0x84; // Obsolete
|
||||
public final static byte PIDATA = (byte) 0x86; // Obsolete
|
||||
public final static byte COMENT = (byte) 0x88;
|
||||
public final static byte MODEND = (byte) 0x8A;
|
||||
public final static byte EXTDEF = (byte) 0x8C;
|
||||
public final static byte TYPDEF = (byte) 0x8E; // Obsolete
|
||||
public final static byte PUBDEF = (byte) 0x90;
|
||||
public final static byte LOCSYM = (byte) 0x92; // Obsolete
|
||||
public final static byte LINNUM = (byte) 0x94;
|
||||
public final static byte LNAMES = (byte) 0x96;
|
||||
public final static byte SEGDEF = (byte) 0x98;
|
||||
public final static byte GRPDEF = (byte) 0x9A;
|
||||
public final static byte FIXUPP = (byte) 0x9C;
|
||||
public final static byte LEDATA = (byte) 0xA0;
|
||||
public final static byte LIDATA = (byte) 0xA2;
|
||||
public final static byte LIBHED = (byte) 0xA4; // Obsolete
|
||||
public final static byte LIBNAM = (byte) 0xA6; // Obsolete
|
||||
public final static byte LIBLOC = (byte) 0xA8; // Obsolete
|
||||
public final static byte LIBDIC = (byte) 0xAA; // Obsolete
|
||||
public final static byte COMDEF = (byte) 0xB0;
|
||||
public final static byte BAKPAT = (byte) 0xB2;
|
||||
public final static byte LEXTDEF = (byte) 0xB4;
|
||||
public final static byte LPUBDEF = (byte) 0xB6;
|
||||
public final static byte LCOMDEF = (byte) 0xB8;
|
||||
public final static byte CEXTDEF = (byte) 0xBC;
|
||||
public final static byte COMDAT = (byte) 0xC2;
|
||||
public final static byte LINSYM = (byte) 0xC4;
|
||||
public final static byte ALIAS = (byte) 0xC6;
|
||||
public final static byte NBKPAT = (byte) 0xC8;
|
||||
public final static byte LLNAMES = (byte) 0xCA;
|
||||
public final static byte VERNUM = (byte) 0xCC;
|
||||
public final static byte VENDEXT = (byte) 0xCE;
|
||||
public final static byte START = (byte) 0xF0;
|
||||
public final static byte END = (byte) 0xF1;
|
||||
|
||||
protected byte recordType;
|
||||
protected int recordLength;
|
||||
protected long recordOffset;
|
||||
protected byte checkSum;
|
||||
|
||||
public byte getRecordType() {
|
||||
|
@ -50,7 +81,12 @@ public abstract class OmfRecord {
|
|||
return recordLength;
|
||||
}
|
||||
|
||||
public long getRecordOffset() {
|
||||
return recordOffset;
|
||||
}
|
||||
|
||||
public void readRecordHeader(BinaryReader reader) throws IOException {
|
||||
recordOffset = reader.getPointerIndex();
|
||||
recordType = reader.readNextByte();
|
||||
recordLength = reader.readNextShort() & 0xffff;
|
||||
}
|
||||
|
@ -63,27 +99,28 @@ public abstract class OmfRecord {
|
|||
byte res = reader.readNextByte();
|
||||
res += reader.readNextByte();
|
||||
res += reader.readNextByte(); // Sum the record header bytes
|
||||
for(int i=0;i<recordLength;++i)
|
||||
for (int i = 0; i < recordLength; ++i)
|
||||
res += reader.readNextByte();
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean validCheckSum(BinaryReader reader) throws IOException {
|
||||
if (checkSum == 0) return true; // Sum compilers just set this to zero
|
||||
if (checkSum == 0)
|
||||
return true; // Sum compilers just set this to zero
|
||||
return (calcCheckSum(reader) == 0);
|
||||
}
|
||||
|
||||
public boolean hasBigFields() {
|
||||
return ((recordType & 1)!=0);
|
||||
return ((recordType & 1) != 0);
|
||||
}
|
||||
|
||||
public static int readInt1Or2(BinaryReader reader,boolean isBig) throws IOException {
|
||||
public static int readInt1Or2(BinaryReader reader, boolean isBig) throws IOException {
|
||||
if (isBig)
|
||||
return (reader.readNextShort() & 0xffff);
|
||||
return (reader.readNextByte() & 0xff);
|
||||
}
|
||||
|
||||
public static int readInt2Or4(BinaryReader reader,boolean isBig) throws IOException {
|
||||
public static int readInt2Or4(BinaryReader reader, boolean isBig) throws IOException {
|
||||
if (isBig)
|
||||
return reader.readNextInt();
|
||||
return (reader.readNextShort() & 0xffff);
|
||||
|
@ -92,81 +129,123 @@ public abstract class OmfRecord {
|
|||
public static int readIndex(BinaryReader reader) throws IOException {
|
||||
int indexWord;
|
||||
byte firstByte = reader.readNextByte();
|
||||
if ((firstByte & 0x80)!=0)
|
||||
if ((firstByte & 0x80) != 0) {
|
||||
indexWord = (firstByte & 0x7f) * 0x100 + (reader.readNextByte() & 0xff);
|
||||
else
|
||||
}
|
||||
else {
|
||||
indexWord = firstByte;
|
||||
}
|
||||
return indexWord;
|
||||
}
|
||||
|
||||
public static OmfRecord readRecord(BinaryReader reader) throws IOException, OmfException {
|
||||
OmfRecord res = null;
|
||||
byte type = reader.peekNextByte();
|
||||
type &= 0xfe; // Mask off the least significant bit
|
||||
switch(type) {
|
||||
type &= 0xfe; // Mask off the least significant bit (16/32 bit flag)
|
||||
return switch (type) {
|
||||
case THEADR:
|
||||
case LHEADR:
|
||||
res = new OmfFileHeader(reader);
|
||||
break;
|
||||
yield new OmfFileHeader(reader);
|
||||
case COMENT:
|
||||
res = new OmfCommentRecord(reader);
|
||||
break;
|
||||
yield new OmfCommentRecord(reader);
|
||||
case MODEND:
|
||||
res = new OmfModuleEnd(reader);
|
||||
break;
|
||||
yield new OmfModuleEnd(reader);
|
||||
case EXTDEF:
|
||||
res = new OmfExternalSymbol(reader,false);
|
||||
break;
|
||||
yield new OmfExternalSymbol(reader, false);
|
||||
case PUBDEF:
|
||||
res = new OmfSymbolRecord(reader,false);
|
||||
break;
|
||||
case LINNUM:
|
||||
res = new OmfLineNumberRecord(reader);
|
||||
break;
|
||||
yield new OmfSymbolRecord(reader, false);
|
||||
case LNAMES:
|
||||
res = new OmfNamesRecord(reader);
|
||||
break;
|
||||
yield new OmfNamesRecord(reader);
|
||||
case SEGDEF:
|
||||
res = new OmfSegmentHeader(reader);
|
||||
break;
|
||||
yield new OmfSegmentHeader(reader);
|
||||
case GRPDEF:
|
||||
res = new OmfGroupRecord(reader);
|
||||
break;
|
||||
yield new OmfGroupRecord(reader);
|
||||
case FIXUPP:
|
||||
res = new OmfFixupRecord(reader);
|
||||
break;
|
||||
yield new OmfFixupRecord(reader);
|
||||
case LEDATA:
|
||||
res = new OmfEnumeratedData(reader);
|
||||
break;
|
||||
yield new OmfEnumeratedData(reader);
|
||||
case LIDATA:
|
||||
res = new OmfIteratedData(reader);
|
||||
break;
|
||||
yield new OmfIteratedData(reader);
|
||||
case COMDEF:
|
||||
res = new OmfComdefRecord(reader,false);
|
||||
break;
|
||||
yield new OmfComdefRecord(reader, false);
|
||||
case LEXTDEF:
|
||||
res = new OmfExternalSymbol(reader,true);
|
||||
break;
|
||||
yield new OmfExternalSymbol(reader, true);
|
||||
case LPUBDEF:
|
||||
res = new OmfSymbolRecord(reader,true);
|
||||
break;
|
||||
yield new OmfSymbolRecord(reader, true);
|
||||
case LCOMDEF:
|
||||
res = new OmfComdefRecord(reader,true);
|
||||
break;
|
||||
yield new OmfComdefRecord(reader, true);
|
||||
case RHEADR:
|
||||
case REGINT:
|
||||
case REDATA:
|
||||
case RIDATA:
|
||||
case OVLDEF:
|
||||
case ENDREC:
|
||||
case BLKDEF:
|
||||
case BLKEND:
|
||||
case DEBSYM:
|
||||
case LINNUM:
|
||||
case PEDATA:
|
||||
case PIDATA:
|
||||
case LIBHED:
|
||||
case LIBNAM:
|
||||
case LIBLOC:
|
||||
case LIBDIC:
|
||||
yield new OmfObsoleteRecord(reader);
|
||||
case LOCSYM:
|
||||
case TYPDEF:
|
||||
case CEXTDEF:
|
||||
case COMDAT:
|
||||
case LINSYM:
|
||||
case ALIAS:
|
||||
case BAKPAT:
|
||||
case NBKPAT:
|
||||
case LLNAMES:
|
||||
case VERNUM:
|
||||
case VENDEXT:
|
||||
yield new OmfUnsupportedRecord(reader);
|
||||
default:
|
||||
throw new OmfException("Unrecognized record type");
|
||||
}
|
||||
return res;
|
||||
yield new OmfUnknownRecord(reader);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the OMF string format, 1-byte length, followed by that many ascii characters
|
||||
* @param reader
|
||||
* @return
|
||||
* @throws IOException
|
||||
* Read the OMF string format: 1-byte length, followed by that many ascii characters
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the string
|
||||
* @return the read OMF string
|
||||
* @throws IOException if an IO-related error occurred
|
||||
*/
|
||||
public static String readString(BinaryReader reader) throws IOException {
|
||||
int count = reader.readNextByte() & 0xff;
|
||||
return reader.readNextAsciiString(count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the given record type
|
||||
*
|
||||
* @param type The record type
|
||||
* @return The name of the given record type
|
||||
*/
|
||||
public final static String getRecordName(int type) {
|
||||
for (Field field : OmfRecord.class.getDeclaredFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
|
||||
try {
|
||||
Byte value = (Byte) field.get(null);
|
||||
if (type == value) {
|
||||
return field.getName();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "<UNKNOWN>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("name: %s, type: 0x%x, offset: 0x%x, length: 0x%x",
|
||||
getRecordName(recordType), recordType, recordOffset, recordLength);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,9 +45,9 @@ public class OmfSegmentHeader extends OmfRecord {
|
|||
private long vma = -1; // assigned (by linker) starting address of segment -1 means unset
|
||||
private ArrayList<OmfData> dataBlocks = new ArrayList<OmfData>();
|
||||
|
||||
OmfSegmentHeader(int num,int datatype) {
|
||||
OmfSegmentHeader(int num, int datatype) {
|
||||
// generate a special Borland header
|
||||
segAttr = (byte)0xa9;
|
||||
segAttr = (byte) 0xa9;
|
||||
segmentLength = 0;
|
||||
segmentNameIndex = 0;
|
||||
classNameIndex = 0;
|
||||
|
@ -62,7 +62,7 @@ public class OmfSegmentHeader extends OmfRecord {
|
|||
else {
|
||||
segmentName = "EXTRA_";
|
||||
}
|
||||
segmentName = segmentName+Integer.toString(num);
|
||||
segmentName = segmentName + Integer.toString(num);
|
||||
if (datatype == 1) {
|
||||
// Treat as a text segment
|
||||
className = "TEXT";
|
||||
|
@ -88,15 +88,15 @@ public class OmfSegmentHeader extends OmfRecord {
|
|||
if (A == 0) {
|
||||
frameNumber = reader.readNextShort() & 0xffff;
|
||||
offset = reader.readNextByte() & 0xff;
|
||||
vma = (long)frameNumber + offset;
|
||||
vma = (long) frameNumber + offset;
|
||||
}
|
||||
segmentLength = OmfRecord.readInt2Or4(reader, hasBigFields) & 0xffffffffL;
|
||||
segmentNameIndex = OmfRecord.readIndex(reader);
|
||||
classNameIndex = OmfRecord.readIndex(reader);
|
||||
overlayNameIndex = OmfRecord.readIndex(reader);
|
||||
readCheckSumByte(reader);
|
||||
int B = (segAttr>>1) & 1;
|
||||
if (B==1) { // Ignore the segmentLength field
|
||||
int B = (segAttr >> 1) & 1;
|
||||
if (B == 1) { // Ignore the segmentLength field
|
||||
if (getRecordType() == OmfRecord.SEGDEF) {
|
||||
segmentLength = 0x10000L; // Exactly 64K segment
|
||||
}
|
||||
|
@ -150,7 +150,8 @@ public class OmfSegmentHeader extends OmfRecord {
|
|||
|
||||
if (isCode) {
|
||||
addrSpace = language.getDefaultSpace();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
addrSpace = language.getDefaultDataSpace();
|
||||
}
|
||||
return addrSpace.getAddress(vma);
|
||||
|
@ -248,22 +249,22 @@ public class OmfSegmentHeader extends OmfRecord {
|
|||
if (alignOverride >= 0) {
|
||||
align = alignOverride;
|
||||
}
|
||||
switch(align) {
|
||||
switch (align) {
|
||||
case 0: // Absolute segment, not relocatable
|
||||
throw new OmfException("Trying to relocate an absolute segment");
|
||||
case 1: // Byte aligned
|
||||
break; // Keep the first valid address
|
||||
case 2: // 2-byte aligned
|
||||
firstValidAddress = (firstValidAddress+1 ) & 0xfffffffffffffffeL;
|
||||
firstValidAddress = (firstValidAddress + 1) & 0xfffffffffffffffeL;
|
||||
break;
|
||||
case 3: // 16-byte aligned
|
||||
firstValidAddress = (firstValidAddress+15) & 0xfffffffffffffff0L;
|
||||
firstValidAddress = (firstValidAddress + 15) & 0xfffffffffffffff0L;
|
||||
break;
|
||||
case 4: // "page" aligned, assume 4096
|
||||
firstValidAddress = (firstValidAddress+4095) & 0xfffffffffffff000L;
|
||||
firstValidAddress = (firstValidAddress + 4095) & 0xfffffffffffff000L;
|
||||
break;
|
||||
case 5: // 4-byte aligned
|
||||
firstValidAddress = (firstValidAddress+3) & 0xfffffffffffffffcL;
|
||||
firstValidAddress = (firstValidAddress + 3) & 0xfffffffffffffffcL;
|
||||
break;
|
||||
default:
|
||||
throw new OmfException("Unsupported alignment type");
|
||||
|
@ -388,10 +389,11 @@ public class OmfSegmentHeader extends OmfRecord {
|
|||
// We have some fill to produce before the next section
|
||||
long size = data.getDataOffset() - pointer;
|
||||
if (size > OmfLoader.MAX_UNINITIALIZED_FILL) {
|
||||
throw new IOException("Unfilled hole in OMF data blocks for segment: "+segmentName);
|
||||
throw new IOException(
|
||||
"Unfilled hole in OMF data blocks for segment: " + segmentName);
|
||||
}
|
||||
buffer = new byte[(int)size];
|
||||
for(int i=0;i<size;++i) {
|
||||
buffer = new byte[(int) size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
buffer[i] = 0;
|
||||
}
|
||||
bufferpointer = 0;
|
||||
|
@ -416,10 +418,10 @@ public class OmfSegmentHeader extends OmfRecord {
|
|||
// We may have filler after the last block
|
||||
long size = segmentLength - pointer;
|
||||
if (size > OmfLoader.MAX_UNINITIALIZED_FILL) {
|
||||
throw new IOException("Large hole at the end of OMF segment: "+segmentName);
|
||||
throw new IOException("Large hole at the end of OMF segment: " + segmentName);
|
||||
}
|
||||
buffer = new byte[(int)size];
|
||||
for(int i=0;i<size;++i) {
|
||||
buffer = new byte[(int) size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
buffer[i] = 0;
|
||||
}
|
||||
bufferpointer = 0;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -23,11 +22,11 @@ public class OmfSymbol {
|
|||
private int typeIndex;
|
||||
private int dataType; // 0=unused
|
||||
private int byteLength; // 0=unused
|
||||
private int segmentRef=0; // Symbol is really reference to extra segment
|
||||
private int segmentRef = 0; // Symbol is really reference to extra segment
|
||||
private long offset;
|
||||
private Address address;
|
||||
|
||||
public OmfSymbol(String name,int type,long off,int dT,int bL) {
|
||||
public OmfSymbol(String name, int type, long off, int dT, int bL) {
|
||||
symbolName = name;
|
||||
typeIndex = type;
|
||||
offset = off;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -28,22 +27,23 @@ public class OmfSymbolRecord extends OmfRecord {
|
|||
private boolean isStatic;
|
||||
private OmfSymbol[] symbol;
|
||||
|
||||
public OmfSymbolRecord(BinaryReader reader,boolean isStatic) throws IOException {
|
||||
public OmfSymbolRecord(BinaryReader reader, boolean isStatic) throws IOException {
|
||||
this.isStatic = isStatic;
|
||||
readRecordHeader(reader);
|
||||
long max = reader.getPointerIndex() + getRecordLength() - 1;
|
||||
boolean hasBigFields = hasBigFields();
|
||||
baseGroupIndex = OmfRecord.readIndex(reader);
|
||||
baseSegmentIndex = OmfRecord.readIndex(reader);
|
||||
if (baseSegmentIndex == 0)
|
||||
if (baseSegmentIndex == 0) {
|
||||
baseFrame = reader.readNextShort() & 0xffff;
|
||||
}
|
||||
|
||||
ArrayList<OmfSymbol> symbollist = new ArrayList<OmfSymbol>();
|
||||
while(reader.getPointerIndex() < max) {
|
||||
while (reader.getPointerIndex() < max) {
|
||||
String name = OmfRecord.readString(reader);
|
||||
long offset = OmfRecord.readInt2Or4(reader, hasBigFields) & 0xffffffffL;
|
||||
int type = OmfRecord.readIndex(reader);
|
||||
OmfSymbol subrec = new OmfSymbol(name,type,offset,0,0);
|
||||
OmfSymbol subrec = new OmfSymbol(name, type, offset, 0, 0);
|
||||
symbollist.add(subrec);
|
||||
}
|
||||
readCheckSumByte(reader);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.omf;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
|
||||
public class OmfUnknownRecord extends OmfRecord {
|
||||
|
||||
/**
|
||||
* Create a new {@link OmfUnknownRecord}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||
* @throws IOException If an IO-related error occurred
|
||||
*/
|
||||
public OmfUnknownRecord(BinaryReader reader) throws IOException {
|
||||
readRecordHeader(reader);
|
||||
reader.setPointerIndex(reader.getPointerIndex() + getRecordLength());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.omf;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
|
||||
public class OmfUnsupportedRecord extends OmfRecord {
|
||||
|
||||
/**
|
||||
* Create a new {@link OmfUnsupportedRecord}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||
* @throws IOException If an IO-related error occurred
|
||||
*/
|
||||
public OmfUnsupportedRecord(BinaryReader reader) throws IOException {
|
||||
readRecordHeader(reader);
|
||||
reader.setPointerIndex(reader.getPointerIndex() + getRecordLength());
|
||||
}
|
||||
}
|
|
@ -38,7 +38,6 @@ import ghidra.util.DataConverter;
|
|||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
public class OmfLoader extends AbstractProgramWrapperLoader {
|
||||
public final static String OMF_NAME = "Relocatable Object Module Format (OMF)";
|
||||
|
@ -115,7 +114,7 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||
OmfFileHeader header = null;
|
||||
BinaryReader reader = OmfFileHeader.createReader(provider);
|
||||
try {
|
||||
header = OmfFileHeader.parse(reader, monitor);
|
||||
header = OmfFileHeader.parse(reader, monitor, log);
|
||||
header.resolveNames();
|
||||
header.sortSegmentDataBlocks();
|
||||
OmfFileHeader.doLinking(IMAGE_BASE, header.getSegments(), header.getGroups());
|
||||
|
@ -284,7 +283,6 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
|||
* @param reader is a reader for the underlying file
|
||||
* @param header is the OMF file header
|
||||
* @param program is the Program
|
||||
* @param mbu is the block creation utility
|
||||
* @param monitor is checked for cancellation
|
||||
* @param log receives error messages
|
||||
* @throws AddressOverflowException if the underlying data stream causes an address to wrap
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue