mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Merge remote-tracking branch
'origin/GP-0_ryanmkurtz_PR-7957_peterbelm_omf51-libfs' (Closes #7957)
This commit is contained in:
commit
fa87e70af4
10 changed files with 624 additions and 5 deletions
|
@ -0,0 +1,72 @@
|
||||||
|
/* ###
|
||||||
|
* 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.omf51;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.format.omf.OmfException;
|
||||||
|
import ghidra.app.util.bin.format.omf.OmfString;
|
||||||
|
|
||||||
|
public class Omf51Library {
|
||||||
|
|
||||||
|
private List<MemberHeader> members = new ArrayList<>();
|
||||||
|
|
||||||
|
public record MemberHeader(long offset, long size, String name) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link Omf51Library}
|
||||||
|
*
|
||||||
|
* @param factory A {@link Omf51RecordFactory}
|
||||||
|
* @throws IOException if an IO-related error occurred
|
||||||
|
* @throws OmfException if the required OMF-51 records could not be read
|
||||||
|
*/
|
||||||
|
public Omf51Library(Omf51RecordFactory factory) throws OmfException, IOException {
|
||||||
|
if (!(factory.readNextRecord() instanceof Omf51LibraryHeaderRecord libraryHeader)) {
|
||||||
|
throw new OmfException("Unable to read library header record");
|
||||||
|
}
|
||||||
|
|
||||||
|
factory.getReader().setPointerIndex(libraryHeader.getModNamesOffset());
|
||||||
|
|
||||||
|
if (!(factory.readNextRecord() instanceof Omf51LibraryModuleNamesRecord modNamesRecord)) {
|
||||||
|
throw new OmfException("Unable to read library module names record");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(factory.readNextRecord() instanceof Omf51LibraryModuleLocationsRecord modLocations)) {
|
||||||
|
throw new OmfException("Unable to read library module locations record");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Omf51LibraryModuleLocation> locations = modLocations.getLocations();
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (OmfString moduleName : modNamesRecord.getNames()) {
|
||||||
|
int currentOffset = locations.get(index).getOffset();
|
||||||
|
int nextOffset = index + 1 < locations.size() ? locations.get(index + 1).getOffset()
|
||||||
|
: libraryHeader.getModNamesOffset();
|
||||||
|
int size = nextOffset - currentOffset;
|
||||||
|
members.add(new MemberHeader(currentOffset, size, moduleName.str()));
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the list of members}
|
||||||
|
*/
|
||||||
|
public List<MemberHeader> getMembers() {
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/* ###
|
||||||
|
* 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.omf51;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.format.omf.*;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
public class Omf51LibraryDictionaryRecord extends OmfRecord {
|
||||||
|
|
||||||
|
private List<List<OmfString>> moduleSymbolMap = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link Omf51LibraryDictionaryRecord}
|
||||||
|
*
|
||||||
|
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||||
|
* @throws IOException if an IO-related error occurred
|
||||||
|
*/
|
||||||
|
public Omf51LibraryDictionaryRecord(BinaryReader reader) throws IOException {
|
||||||
|
super(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parseData() throws IOException, OmfException {
|
||||||
|
List<OmfString> symbols = new ArrayList<>();
|
||||||
|
|
||||||
|
while (dataReader.getPointerIndex() < dataEnd) {
|
||||||
|
byte len = dataReader.peekNextByte();
|
||||||
|
if (len == 0) {
|
||||||
|
dataReader.readNextByte();
|
||||||
|
moduleSymbolMap.add(symbols);
|
||||||
|
symbols = new ArrayList<>();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
symbols.add(OmfUtils.readString(dataReader));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
|
StructureDataType struct = new StructureDataType(Omf51RecordTypes.getName(recordType), 0);
|
||||||
|
struct.add(BYTE, "type", null);
|
||||||
|
struct.add(WORD, "length", null);
|
||||||
|
Integer moduleIndex = 0;
|
||||||
|
for (List<OmfString> symbols : moduleSymbolMap) {
|
||||||
|
for (OmfString symbol : symbols) {
|
||||||
|
struct.add(symbol.toDataType(), symbol.getDataTypeSize(),
|
||||||
|
"symbol%d".formatted(moduleIndex), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct.add(BYTE, "terminator%d".formatted(moduleIndex), null);
|
||||||
|
moduleIndex++;
|
||||||
|
}
|
||||||
|
struct.add(BYTE, "checksum", null);
|
||||||
|
|
||||||
|
struct.setCategoryPath(new CategoryPath(OmfUtils.CATEGORY_PATH));
|
||||||
|
return struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the symbol names partitioned by module}
|
||||||
|
*/
|
||||||
|
public List<List<OmfString>> getModuleSymbolMap() {
|
||||||
|
return moduleSymbolMap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/* ###
|
||||||
|
* 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.omf51;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.format.omf.*;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
public class Omf51LibraryHeaderRecord extends OmfRecord {
|
||||||
|
|
||||||
|
public static final int BLOCK_SIZE = 128;
|
||||||
|
|
||||||
|
private short moduleCount;
|
||||||
|
private short blockNumber;
|
||||||
|
private short byteNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link Omf51LibraryHeaderRecord} record
|
||||||
|
*
|
||||||
|
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||||
|
* @throws IOException if an IO-related error occurred
|
||||||
|
*/
|
||||||
|
public Omf51LibraryHeaderRecord(BinaryReader reader) throws IOException {
|
||||||
|
super(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parseData() throws IOException, OmfException {
|
||||||
|
moduleCount = dataReader.readNextShort();
|
||||||
|
blockNumber = dataReader.readNextShort();
|
||||||
|
byteNumber = dataReader.readNextShort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
|
StructureDataType struct = new StructureDataType(Omf51RecordTypes.getName(recordType), 0);
|
||||||
|
struct.add(BYTE, "type", null);
|
||||||
|
struct.add(WORD, "length", null);
|
||||||
|
struct.add(WORD, "moduleCount", null);
|
||||||
|
struct.add(WORD, "blockNumber", null);
|
||||||
|
struct.add(WORD, "byteNumber", null);
|
||||||
|
struct.add(BYTE, "checksum", null);
|
||||||
|
|
||||||
|
struct.setCategoryPath(new CategoryPath(OmfUtils.CATEGORY_PATH));
|
||||||
|
return struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the module count}
|
||||||
|
*/
|
||||||
|
public short getModuleCount() {
|
||||||
|
return moduleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the module names block number}
|
||||||
|
*/
|
||||||
|
public short getModNamesBlockNumber() {
|
||||||
|
return blockNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the module names byte number}
|
||||||
|
*/
|
||||||
|
public short getModNamesByteNumber() {
|
||||||
|
return byteNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the module names file offset}
|
||||||
|
*/
|
||||||
|
public int getModNamesOffset() {
|
||||||
|
return (blockNumber * BLOCK_SIZE) + byteNumber;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* ###
|
||||||
|
* 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.omf51;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.StructConverter;
|
||||||
|
import ghidra.app.util.bin.format.omf.OmfUtils;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
|
||||||
|
public class Omf51LibraryModuleLocation {
|
||||||
|
|
||||||
|
public static final int BLOCK_SIZE = 128;
|
||||||
|
|
||||||
|
private int blockNumber;
|
||||||
|
private int byteNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link Omf51LibraryModuleLocation}
|
||||||
|
*
|
||||||
|
* @param reader A {@link BinaryReader} positioned at the start of the segment definition
|
||||||
|
* @throws IOException if an IO-related error occurred
|
||||||
|
*/
|
||||||
|
public Omf51LibraryModuleLocation(BinaryReader reader) throws IOException {
|
||||||
|
blockNumber = reader.readNextUnsignedShort();
|
||||||
|
byteNumber = reader.readNextUnsignedShort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the block number}
|
||||||
|
*/
|
||||||
|
public int getBlockNumber() {
|
||||||
|
return blockNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the byte number}
|
||||||
|
*/
|
||||||
|
public int getByteNumber() {
|
||||||
|
return byteNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the offset into the library}
|
||||||
|
*/
|
||||||
|
public int getOffset() {
|
||||||
|
return (blockNumber * BLOCK_SIZE) + byteNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataType toDataType() {
|
||||||
|
StructureDataType struct = new StructureDataType("Omf51LibraryModuleLocation", 0);
|
||||||
|
struct.add(StructConverter.WORD, "blockNumber", null);
|
||||||
|
struct.add(StructConverter.WORD, "byteNumber", null);
|
||||||
|
struct.setCategoryPath(new CategoryPath(OmfUtils.CATEGORY_PATH));
|
||||||
|
return struct;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* ###
|
||||||
|
* 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.omf51;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.format.omf.*;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
public class Omf51LibraryModuleLocationsRecord extends OmfRecord {
|
||||||
|
|
||||||
|
private List<Omf51LibraryModuleLocation> locations = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link Omf51LibraryModuleLocationsRecord} record
|
||||||
|
*
|
||||||
|
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||||
|
* @throws IOException if an IO-related error occurred
|
||||||
|
*/
|
||||||
|
public Omf51LibraryModuleLocationsRecord(BinaryReader reader) throws IOException {
|
||||||
|
super(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parseData() throws IOException, OmfException {
|
||||||
|
while (dataReader.getPointerIndex() < dataEnd) {
|
||||||
|
locations.add(new Omf51LibraryModuleLocation(dataReader));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
|
StructureDataType struct = new StructureDataType(Omf51RecordTypes.getName(recordType), 0);
|
||||||
|
struct.add(BYTE, "type", null);
|
||||||
|
struct.add(WORD, "length", null);
|
||||||
|
struct.add(new ArrayDataType(Omf51LibraryModuleLocation.toDataType(), locations.size()),
|
||||||
|
"locations", null);
|
||||||
|
struct.add(BYTE, "checksum", null);
|
||||||
|
|
||||||
|
struct.setCategoryPath(new CategoryPath(OmfUtils.CATEGORY_PATH));
|
||||||
|
return struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the list of module locations}
|
||||||
|
*/
|
||||||
|
public List<Omf51LibraryModuleLocation> getLocations() {
|
||||||
|
return locations;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* ###
|
||||||
|
* 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.omf51;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.format.omf.*;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
public class Omf51LibraryModuleNamesRecord extends OmfRecord {
|
||||||
|
|
||||||
|
private List<OmfString> names = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link Omf51LibraryModuleNamesRecord} record
|
||||||
|
*
|
||||||
|
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||||
|
* @throws IOException if an IO-related error occurred
|
||||||
|
*/
|
||||||
|
public Omf51LibraryModuleNamesRecord(BinaryReader reader) throws IOException {
|
||||||
|
super(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parseData() throws IOException, OmfException {
|
||||||
|
while (dataReader.getPointerIndex() < dataEnd) {
|
||||||
|
names.add(OmfUtils.readString(dataReader));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
|
StructureDataType struct = new StructureDataType(Omf51RecordTypes.getName(recordType), 0);
|
||||||
|
struct.add(BYTE, "type", null);
|
||||||
|
struct.add(WORD, "length", null);
|
||||||
|
for (OmfString name : names) {
|
||||||
|
struct.add(name.toDataType(), name.getDataTypeSize(), "name", null);
|
||||||
|
}
|
||||||
|
struct.add(BYTE, "checksum", null);
|
||||||
|
|
||||||
|
struct.setCategoryPath(new CategoryPath(OmfUtils.CATEGORY_PATH));
|
||||||
|
return struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the list of module names}
|
||||||
|
*/
|
||||||
|
public List<OmfString> getNames() {
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
}
|
|
@ -70,12 +70,16 @@ public class Omf51RecordFactory extends AbstractOmfRecordFactory {
|
||||||
yield new Omf51ExternalDefsRecord(reader, false);
|
yield new Omf51ExternalDefsRecord(reader, false);
|
||||||
case KeilExternalDEF:
|
case KeilExternalDEF:
|
||||||
yield new Omf51ExternalDefsRecord(reader, true);
|
yield new Omf51ExternalDefsRecord(reader, true);
|
||||||
|
case LibModLocs:
|
||||||
|
yield new Omf51LibraryModuleLocationsRecord(reader);
|
||||||
|
case LibModNames:
|
||||||
|
yield new Omf51LibraryModuleNamesRecord(reader);
|
||||||
|
case LibDictionary:
|
||||||
|
yield new Omf51LibraryDictionaryRecord(reader);
|
||||||
|
case LibHeader:
|
||||||
|
yield new Omf51LibraryHeaderRecord(reader);
|
||||||
case ScopeDEF:
|
case ScopeDEF:
|
||||||
case DebugItem:
|
case DebugItem:
|
||||||
case LibModLocs:
|
|
||||||
case LibModNames:
|
|
||||||
case LibDictionary:
|
|
||||||
case LibHeader:
|
|
||||||
yield new OmfUnsupportedRecord(reader, Omf51RecordTypes.class);
|
yield new OmfUnsupportedRecord(reader, Omf51RecordTypes.class);
|
||||||
default:
|
default:
|
||||||
yield new OmfUnknownRecord(reader);
|
yield new OmfUnknownRecord(reader);
|
||||||
|
|
|
@ -338,7 +338,6 @@ public class Omf51Loader extends AbstractProgramWrapperLoader {
|
||||||
if (record instanceof Omf51PublicDefsRecord publicDefRec) {
|
if (record instanceof Omf51PublicDefsRecord publicDefRec) {
|
||||||
for (Omf51PublicDef def : publicDefRec.getDefinitions()) {
|
for (Omf51PublicDef def : publicDefRec.getDefinitions()) {
|
||||||
if (def.getUsageType() == Omf51PublicDef.NUMBER) {
|
if (def.getUsageType() == Omf51PublicDef.NUMBER) {
|
||||||
log.appendMsg("Skipping NUMBER public def");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Address segmentAddr = segmentToAddr.get(def.getSegId());
|
Address segmentAddr = segmentToAddr.get(def.getSegId());
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/* ###
|
||||||
|
* 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.file.formats.omf51;
|
||||||
|
|
||||||
|
import static ghidra.formats.gfilesystem.fileinfo.FileAttributeType.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
|
import ghidra.app.util.bin.ByteProviderWrapper;
|
||||||
|
import ghidra.app.util.bin.format.omf.OmfException;
|
||||||
|
import ghidra.app.util.bin.format.omf.omf51.Omf51Library;
|
||||||
|
import ghidra.app.util.bin.format.omf.omf51.Omf51RecordFactory;
|
||||||
|
import ghidra.formats.gfilesystem.*;
|
||||||
|
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||||
|
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
||||||
|
import ghidra.util.exception.CancelledException;
|
||||||
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@FileSystemInfo(
|
||||||
|
type = "omf51",
|
||||||
|
description = "OMF51 Library",
|
||||||
|
factory = Omf51ArchiveFileSystemFactory.class
|
||||||
|
)
|
||||||
|
public class Omf51ArchiveFileSystem extends AbstractFileSystem<Omf51Library.MemberHeader> {
|
||||||
|
|
||||||
|
private ByteProvider provider;
|
||||||
|
|
||||||
|
public Omf51ArchiveFileSystem(FSRLRoot fsFSRL, ByteProvider provider) {
|
||||||
|
super(fsFSRL, FileSystemService.getInstance());
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mount(TaskMonitor monitor) throws IOException, OmfException, CancelledException {
|
||||||
|
monitor.setMessage("Opening OMF51 library...");
|
||||||
|
Omf51RecordFactory factory = new Omf51RecordFactory(provider);
|
||||||
|
List<Omf51Library.MemberHeader> members = new Omf51Library(factory).getMembers();
|
||||||
|
|
||||||
|
monitor.initialize(members.size(), "Opening OMF51 library...");
|
||||||
|
for (Omf51Library.MemberHeader member : members) {
|
||||||
|
monitor.increment();
|
||||||
|
fsIndex.storeFile(member.name(), fsIndex.getFileCount(), false, member.size(), member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
refManager.onClose();
|
||||||
|
if (provider != null) {
|
||||||
|
provider.close();
|
||||||
|
provider = null;
|
||||||
|
}
|
||||||
|
fsIndex.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return provider == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteProvider getByteProvider(GFile file, TaskMonitor monitor) {
|
||||||
|
Omf51Library.MemberHeader member = fsIndex.getMetadata(file);
|
||||||
|
return (member != null)
|
||||||
|
? new ByteProviderWrapper(provider, member.offset(), member.size(),
|
||||||
|
file.getFSRL())
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileAttributes getFileAttributes(GFile file, TaskMonitor monitor) {
|
||||||
|
FileAttributes result = new FileAttributes();
|
||||||
|
|
||||||
|
Omf51Library.MemberHeader entry = fsIndex.getMetadata(file);
|
||||||
|
if (entry != null) {
|
||||||
|
result.add(NAME_ATTR, entry.name());
|
||||||
|
result.add(SIZE_ATTR, entry.size());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* ###
|
||||||
|
* 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.file.formats.omf51;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
|
import ghidra.app.util.bin.format.omf.AbstractOmfRecordFactory;
|
||||||
|
import ghidra.app.util.bin.format.omf.OmfException;
|
||||||
|
import ghidra.app.util.bin.format.omf.omf51.Omf51LibraryHeaderRecord;
|
||||||
|
import ghidra.app.util.bin.format.omf.omf51.Omf51RecordFactory;
|
||||||
|
import ghidra.app.util.opinion.Omf51Loader;
|
||||||
|
import ghidra.formats.gfilesystem.FSRLRoot;
|
||||||
|
import ghidra.formats.gfilesystem.FileSystemService;
|
||||||
|
import ghidra.formats.gfilesystem.factory.GFileSystemFactoryByteProvider;
|
||||||
|
import ghidra.formats.gfilesystem.factory.GFileSystemProbeByteProvider;
|
||||||
|
import ghidra.util.exception.CancelledException;
|
||||||
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
public class Omf51ArchiveFileSystemFactory implements
|
||||||
|
GFileSystemFactoryByteProvider<Omf51ArchiveFileSystem>, GFileSystemProbeByteProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Omf51ArchiveFileSystem create(FSRLRoot targetFSRL, ByteProvider byteProvider,
|
||||||
|
FileSystemService fsService, TaskMonitor monitor)
|
||||||
|
throws IOException, CancelledException {
|
||||||
|
|
||||||
|
Omf51ArchiveFileSystem fs = new Omf51ArchiveFileSystem(targetFSRL, byteProvider);
|
||||||
|
try {
|
||||||
|
fs.mount(monitor);
|
||||||
|
}
|
||||||
|
catch (OmfException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean probe(ByteProvider byteProvider, FileSystemService fsService,
|
||||||
|
TaskMonitor monitor) throws IOException, CancelledException {
|
||||||
|
|
||||||
|
if (byteProvider.length() < Omf51Loader.MIN_BYTE_LENGTH) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
AbstractOmfRecordFactory factory = new Omf51RecordFactory(byteProvider);
|
||||||
|
return factory.readNextRecord() instanceof Omf51LibraryHeaderRecord;
|
||||||
|
}
|
||||||
|
catch (OmfException | IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue