GP-0: Allowing OMF-51 files to load even if reading records caused

exception
This commit is contained in:
Ryan Kurtz
2026-03-27 06:43:26 -04:00
parent f71e1f6035
commit 9da1425d73
6 changed files with 39 additions and 20 deletions

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,20 +18,23 @@ package ghidra.app.util.bin.format.omf;
import java.io.IOException;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.omf.omf.OmfRecordTypes;
import ghidra.program.model.data.DataType;
import ghidra.util.exception.DuplicateNameException;
public class OmfObsoleteRecord extends OmfRecord {
private Class<?> recordTypesClass;
/**
* Create a new {@link OmfObsoleteRecord}
*
* @param reader A {@link BinaryReader} positioned at the start of the record
* @param recordTypesClass The class that contains accessible OMF type fields
* @throws IOException If an IO-related error occurred
*/
public OmfObsoleteRecord(BinaryReader reader) throws IOException {
public OmfObsoleteRecord(BinaryReader reader, Class<?> recordTypesClass) throws IOException {
super(reader);
this.recordTypesClass = recordTypesClass;
}
@Override
@@ -41,6 +44,7 @@ public class OmfObsoleteRecord extends OmfRecord {
@Override
public DataType toDataType() throws DuplicateNameException, IOException {
return OmfUtils.toOmfRecordDataType(this, OmfRecordTypes.getName(recordType));
return OmfUtils.toOmfRecordDataType(this,
OmfUtils.getRecordName(recordType, recordTypesClass));
}
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,7 +18,6 @@ package ghidra.app.util.bin.format.omf;
import java.io.IOException;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.omf.omf.OmfRecordTypes;
import ghidra.program.model.data.DataType;
import ghidra.util.exception.DuplicateNameException;
@@ -27,14 +26,18 @@ import ghidra.util.exception.DuplicateNameException;
*/
public class OmfUnknownRecord extends OmfRecord {
private Class<?> recordTypesClass;
/**
* Create a new {@link OmfUnknownRecord}
*
* @param reader A {@link BinaryReader} positioned at the start of the record
* @param recordTypesClass The class that contains accessible OMF type fields
* @throws IOException If an IO-related error occurred
*/
public OmfUnknownRecord(BinaryReader reader) throws IOException {
public OmfUnknownRecord(BinaryReader reader, Class<?> recordTypesClass) throws IOException {
super(reader);
this.recordTypesClass = recordTypesClass;
}
@Override
@@ -44,6 +47,7 @@ public class OmfUnknownRecord extends OmfRecord {
@Override
public DataType toDataType() throws DuplicateNameException, IOException {
return OmfUtils.toOmfRecordDataType(this, OmfRecordTypes.getName(recordType));
return OmfUtils.toOmfRecordDataType(this,
OmfUtils.getRecordName(recordType, recordTypesClass));
}
}

View File

@@ -23,6 +23,7 @@ import java.util.List;
import java.util.stream.Stream;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.importer.MessageLog;
import ghidra.program.model.data.*;
/**
@@ -126,19 +127,29 @@ public class OmfUtils {
* {@link AbstractOmfRecordFactory}
*
* @param factory The {@link AbstractOmfRecordFactory}
* @param log The log
* @return A {@link List} of read {@link OmfRecord records}
* @throws IOException if there was an IO-related error
* @throws OmfException if there was a problem with the OMF specification
*/
public static List<OmfRecord> readRecords(AbstractOmfRecordFactory factory)
public static List<OmfRecord> readRecords(AbstractOmfRecordFactory factory, MessageLog log)
throws OmfException, IOException {
List<OmfRecord> records = new ArrayList<>();
factory.reset();
while (true) {
OmfRecord rec = factory.readNextRecord();
records.add(rec);
if (rec.getRecordType() == factory.getEndRecordType()) {
try {
OmfRecord rec = factory.readNextRecord();
if (!rec.validCheckSum()) {
log.appendMsg("OMF record [%s] has an invalid checksum".formatted(rec));
}
records.add(rec);
if (rec.getRecordType() == factory.getEndRecordType()) {
break;
}
}
catch (IOException e) {
log.appendException(e);
break;
}
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -91,7 +91,7 @@ public class OmfRecordFactory extends AbstractOmfRecordFactory {
case LIBNAM:
case LIBLOC:
case LIBDIC:
yield new OmfObsoleteRecord(reader);
yield new OmfObsoleteRecord(reader, OmfRecordTypes.class);
case LOCSYM:
case TYPDEF:
case COMDAT:
@@ -104,7 +104,7 @@ public class OmfRecordFactory extends AbstractOmfRecordFactory {
case VENDEXT:
yield new OmfUnsupportedRecord(reader, OmfRecordTypes.class);
default:
yield new OmfUnknownRecord(reader);
yield new OmfUnknownRecord(reader, OmfRecordTypes.class);
};
record.parseData();

View File

@@ -82,7 +82,7 @@ public class Omf51RecordFactory extends AbstractOmfRecordFactory {
case DebugItem:
yield new OmfUnsupportedRecord(reader, Omf51RecordTypes.class);
default:
yield new OmfUnknownRecord(reader);
yield new OmfUnknownRecord(reader, Omf51RecordTypes.class);
};
record.parseData();

View File

@@ -82,7 +82,7 @@ public class Omf51Loader extends AbstractProgramWrapperLoader {
MemoryBlockUtils.createFileBytes(program, settings.provider(), monitor);
AbstractOmfRecordFactory factory = new Omf51RecordFactory(settings.provider());
try {
List<OmfRecord> records = OmfUtils.readRecords(factory);
List<OmfRecord> records = OmfUtils.readRecords(factory, settings.log());
Map<Integer, Address> segmentToAddr =
processMemoryBlocks(program, fileBytes, records, log, monitor);
Map<Integer, Address> extIdToAddr =