mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 10:56:29 +08:00
GP-3182: Certify and cleanup
This commit is contained in:
+168
-190
File diff suppressed because it is too large
Load Diff
+15
-24
@@ -18,25 +18,17 @@ package ghidra.app.util.bin.format.unixaout;
|
||||
|
||||
public class UnixAoutMachineType {
|
||||
|
||||
// These values come from a combination of sources, including NetBSD's
|
||||
// aout_mids.h
|
||||
// and the GNU BFD Library's libaout.h.
|
||||
// These values come from a combination of sources, including NetBSD's aout_mids.h and the GNU
|
||||
// BFD Library's libaout.h.
|
||||
//
|
||||
// Note: some a.out header files list a few HP values (for the 300 Series, 800
|
||||
// Series, etc.)
|
||||
// and these values exceed a full eight-bit count. Occasionally, this is
|
||||
// accounted for by
|
||||
// extending the Machine ID field of the a_magic word two bits higher, leaving
|
||||
// only six bits
|
||||
// in the MSB for other flags. This may not be correct, because those high-value
|
||||
// HP machine
|
||||
// IDs probably only appear in HP UX binaries, which use a different format.
|
||||
// (This format is
|
||||
// still named "a.out", but has a completely different header and internal
|
||||
// organization.)
|
||||
// The 10-bit Machine ID field would also interfere with flags used by VxWorks,
|
||||
// NetBSD, and
|
||||
// probably others.
|
||||
// Note: some a.out header files list a few HP values (for the 300 Series, 800 Series, etc.)
|
||||
// and these values exceed a full eight-bit count. Occasionally, this is accounted for by
|
||||
// extending the Machine ID field of the a_magic word two bits higher, leaving only six bits in
|
||||
// the MSB for other flags. This may not be correct, because those high-value HP machine IDs
|
||||
// probably only appear in HP UX binaries, which use a different format. (This format is still
|
||||
// named "a.out", but has a completely different header and internal organization.) The 10-bit
|
||||
// Machine ID field would also interfere with flags used by VxWorks, NetBSD, and probably
|
||||
// others.
|
||||
|
||||
public final static short M_UNKNOWN = 0x00;
|
||||
public final static short M_68010 = 0x01;
|
||||
@@ -78,10 +70,9 @@ public class UnixAoutMachineType {
|
||||
public final static short M_RISCV = 0xb9; // RISC-V
|
||||
public final static short M_CRIS = 0xff; // Axis ETRAX CRIS
|
||||
|
||||
/**
|
||||
* Machine IDs that should only appear in the incompatible HP UX a.out format:
|
||||
* HP300 (68020+68881): 0x12c
|
||||
* HP200/300 : 0x20c
|
||||
* HP800 : 0x20b
|
||||
*/
|
||||
// Machine IDs that should only appear in the incompatible HP UX a.out format:
|
||||
//
|
||||
// HP300 (68020+68881): 0x12c
|
||||
// HP200/300 : 0x20c
|
||||
// HP800 : 0x20b
|
||||
}
|
||||
|
||||
+13
-13
@@ -37,8 +37,8 @@ public class UnixAoutRelocation {
|
||||
/**
|
||||
*
|
||||
* @param address First of the two words in the table entry (a 32-bit address)
|
||||
* @param flags Second of the two words in the table entry (containing several
|
||||
* bitfields)
|
||||
* @param flags Second of the two words in the table entry (containing several bitfields)
|
||||
* @param bigEndian True if big endian; otherwise, false
|
||||
*/
|
||||
public UnixAoutRelocation(long address, long flags, boolean bigEndian) {
|
||||
this.address = (0xFFFFFFFF & address);
|
||||
@@ -53,7 +53,8 @@ public class UnixAoutRelocation {
|
||||
this.jmpTable = ((flags & 0x4) != 0);
|
||||
this.relative = ((flags & 0x2) != 0);
|
||||
this.copy = ((flags & 0x1) != 0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this.symbolNum = (int) (flags & 0x00FFFFFF);
|
||||
this.flags = (byte) ((flags & 0xFF000000) >> 24);
|
||||
this.pcRelativeAddressing = ((this.flags & 0x01) != 0);
|
||||
@@ -67,17 +68,16 @@ public class UnixAoutRelocation {
|
||||
}
|
||||
|
||||
public String getSymbolName(UnixAoutSymbolTable symtab) {
|
||||
if (extern == true && symbolNum < symtab.size()) {
|
||||
if (extern && symbolNum < symtab.size()) {
|
||||
return symtab.get(symbolNum).name;
|
||||
} else if (extern == false) {
|
||||
switch (symbolNum) {
|
||||
case 4:
|
||||
return UnixAoutProgramLoader.dot_text;
|
||||
case 6:
|
||||
return UnixAoutProgramLoader.dot_data;
|
||||
case 8:
|
||||
return UnixAoutProgramLoader.dot_bss;
|
||||
}
|
||||
}
|
||||
else if (!extern) {
|
||||
return switch (symbolNum) {
|
||||
case 4 -> UnixAoutProgramLoader.dot_text;
|
||||
case 6 -> UnixAoutProgramLoader.dot_data;
|
||||
case 8 -> UnixAoutProgramLoader.dot_bss;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+10
-18
@@ -16,24 +16,14 @@
|
||||
package ghidra.app.util.bin.format.unixaout;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.program.model.data.ArrayDataType;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.InvalidDataTypeException;
|
||||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Listing;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
@@ -45,8 +35,8 @@ public class UnixAoutRelocationTable implements Iterable<UnixAoutRelocation>, St
|
||||
private final List<UnixAoutRelocation> relocations;
|
||||
private final UnixAoutSymbolTable symtab;
|
||||
|
||||
public UnixAoutRelocationTable(BinaryReader reader, long fileOffset, long fileSize, UnixAoutSymbolTable symtab)
|
||||
throws IOException {
|
||||
public UnixAoutRelocationTable(BinaryReader reader, long fileOffset, long fileSize,
|
||||
UnixAoutSymbolTable symtab) throws IOException {
|
||||
this.fileSize = fileSize;
|
||||
this.relocations = new ArrayList<>();
|
||||
this.symtab = symtab;
|
||||
@@ -58,7 +48,8 @@ public class UnixAoutRelocationTable implements Iterable<UnixAoutRelocation>, St
|
||||
long address = reader.readNextUnsignedInt();
|
||||
long flags = reader.readNextUnsignedInt();
|
||||
|
||||
UnixAoutRelocation relocation = new UnixAoutRelocation(address, flags, reader.isBigEndian());
|
||||
UnixAoutRelocation relocation =
|
||||
new UnixAoutRelocation(address, flags, reader.isBigEndian());
|
||||
relocations.add(relocation);
|
||||
}
|
||||
}
|
||||
@@ -83,7 +74,8 @@ public class UnixAoutRelocationTable implements Iterable<UnixAoutRelocation>, St
|
||||
struct.addBitField(BYTE, 1, "r_jmptable", null);
|
||||
struct.addBitField(BYTE, 1, "r_relative", null);
|
||||
struct.addBitField(BYTE, 1, "r_copy", null);
|
||||
} catch (InvalidDataTypeException e) {
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -101,7 +93,7 @@ public class UnixAoutRelocationTable implements Iterable<UnixAoutRelocation>, St
|
||||
|
||||
if (!StringUtils.isBlank(name)) {
|
||||
Data structData = array.getComponent(idx);
|
||||
structData.setComment(CodeUnit.EOL_COMMENT, name);
|
||||
structData.setComment(CommentType.EOL, name);
|
||||
}
|
||||
|
||||
idx++;
|
||||
|
||||
+5
-6
@@ -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.
|
||||
@@ -21,9 +21,7 @@ import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.TerminatedStringDataType;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Listing;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
|
||||
@@ -42,7 +40,8 @@ public class UnixAoutStringTable {
|
||||
}
|
||||
try {
|
||||
return reader.readUtf8String(fileOffset + stringOffset).trim();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
catch (IOException e) {
|
||||
// FIXME
|
||||
}
|
||||
return null;
|
||||
|
||||
+17
-43
@@ -38,55 +38,29 @@ public class UnixAoutSymbol {
|
||||
public long value;
|
||||
public boolean isExt;
|
||||
|
||||
public UnixAoutSymbol(long nameStringOffset, byte typeByte, byte otherByte,
|
||||
short desc, long value) {
|
||||
public UnixAoutSymbol(long nameStringOffset, byte typeByte, byte otherByte, short desc,
|
||||
long value) {
|
||||
this.nameStringOffset = nameStringOffset;
|
||||
this.otherByte = otherByte;
|
||||
this.desc = desc;
|
||||
this.value = value;
|
||||
this.isExt = (typeByte & 1) == 1;
|
||||
|
||||
switch (typeByte & 0xfe) {
|
||||
case 0:
|
||||
type = SymbolType.N_UNDF;
|
||||
break;
|
||||
case 2:
|
||||
type = SymbolType.N_ABS;
|
||||
break;
|
||||
case 4:
|
||||
type = SymbolType.N_TEXT;
|
||||
break;
|
||||
case 6:
|
||||
type = SymbolType.N_DATA;
|
||||
break;
|
||||
case 8:
|
||||
type = SymbolType.N_BSS;
|
||||
break;
|
||||
case 10:
|
||||
type = SymbolType.N_INDR;
|
||||
break;
|
||||
default:
|
||||
if ((typeByte & 0xfe) >= 0x20) {
|
||||
type = SymbolType.N_STAB;
|
||||
} else {
|
||||
type = SymbolType.UNKNOWN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.type = switch (typeByte & 0xfe) {
|
||||
case 0 -> SymbolType.N_UNDF;
|
||||
case 2 -> SymbolType.N_ABS;
|
||||
case 4 -> SymbolType.N_TEXT;
|
||||
case 6 -> SymbolType.N_DATA;
|
||||
case 8 -> SymbolType.N_BSS;
|
||||
case 10 -> SymbolType.N_INDR;
|
||||
default -> (typeByte & 0xfe) >= 0x20 ? SymbolType.N_STAB : SymbolType.UNKNOWN;
|
||||
};
|
||||
|
||||
switch (otherByte & 0x0f) {
|
||||
case 1:
|
||||
kind = SymbolKind.AUX_OBJECT;
|
||||
break;
|
||||
case 2:
|
||||
kind = SymbolKind.AUX_FUNC;
|
||||
break;
|
||||
case 3:
|
||||
kind = SymbolKind.AUX_LABEL;
|
||||
break;
|
||||
default:
|
||||
kind = SymbolKind.UNKNOWN;
|
||||
break;
|
||||
}
|
||||
this.kind = switch (otherByte & 0x0f) {
|
||||
case 1 -> SymbolKind.AUX_OBJECT;
|
||||
case 2 -> SymbolKind.AUX_FUNC;
|
||||
case 3 -> SymbolKind.AUX_LABEL;
|
||||
default -> SymbolKind.UNKNOWN;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+16
-23
@@ -16,9 +16,7 @@
|
||||
package ghidra.app.util.bin.format.unixaout;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -26,15 +24,8 @@ import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.opinion.UnixAoutProgramLoader;
|
||||
import ghidra.program.model.data.ArrayDataType;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.data.StructureDataType;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Listing;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
@@ -45,8 +36,8 @@ public class UnixAoutSymbolTable implements Iterable<UnixAoutSymbol>, StructConv
|
||||
private final long fileSize;
|
||||
private List<UnixAoutSymbol> symbols;
|
||||
|
||||
public UnixAoutSymbolTable(BinaryReader reader, long fileOffset, long fileSize, UnixAoutStringTable strtab, MessageLog log)
|
||||
throws IOException {
|
||||
public UnixAoutSymbolTable(BinaryReader reader, long fileOffset, long fileSize,
|
||||
UnixAoutStringTable strtab, MessageLog log) throws IOException {
|
||||
this.fileSize = fileSize;
|
||||
this.symbols = new ArrayList<>();
|
||||
|
||||
@@ -63,7 +54,8 @@ public class UnixAoutSymbolTable implements Iterable<UnixAoutSymbol>, StructConv
|
||||
|
||||
UnixAoutSymbol symbol = new UnixAoutSymbol(strOffset, typeByte, otherByte, desc, value);
|
||||
if (symbol.type == UnixAoutSymbol.SymbolType.UNKNOWN) {
|
||||
log.appendMsg(UnixAoutProgramLoader.dot_symtab, String.format("Unknown symbol type 0x%02x at symbol index %d", typeByte, idx));
|
||||
log.appendMsg(UnixAoutProgramLoader.dot_symtab,
|
||||
String.format("Unknown symbol type 0x%02x at symbol index %d", typeByte, idx));
|
||||
}
|
||||
symbols.add(symbol);
|
||||
|
||||
@@ -93,15 +85,16 @@ public class UnixAoutSymbolTable implements Iterable<UnixAoutSymbol>, StructConv
|
||||
return new ArrayDataType(struct, (int) (fileSize / ENTRY_SIZE), ENTRY_SIZE);
|
||||
}
|
||||
|
||||
public UnixAoutSymbol get(int symbolNum) {
|
||||
return symbols.get(symbolNum);
|
||||
}
|
||||
public UnixAoutSymbol get(int symbolNum) {
|
||||
return symbols.get(symbolNum);
|
||||
}
|
||||
|
||||
public long size() {
|
||||
return symbols.size();
|
||||
}
|
||||
public long size() {
|
||||
return symbols.size();
|
||||
}
|
||||
|
||||
public void markup(Program program, MemoryBlock block) throws CodeUnitInsertionException, DuplicateNameException, IOException {
|
||||
public void markup(Program program, MemoryBlock block)
|
||||
throws CodeUnitInsertionException, DuplicateNameException, IOException {
|
||||
Listing listing = program.getListing();
|
||||
Data array = listing.createData(block.getStart(), toDataType());
|
||||
|
||||
@@ -111,7 +104,7 @@ public class UnixAoutSymbolTable implements Iterable<UnixAoutSymbol>, StructConv
|
||||
Data structData = array.getComponent(idx);
|
||||
|
||||
if (structData != null) {
|
||||
structData.setComment(CodeUnit.EOL_COMMENT, symbol.name);
|
||||
structData.setComment(CommentType.EOL, symbol.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
package ghidra.app.util.opinion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.util.Option;
|
||||
import ghidra.app.util.OptionException;
|
||||
@@ -26,9 +24,7 @@ import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.bin.format.unixaout.UnixAoutHeader;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.LanguageCompilerSpecPair;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
@@ -36,46 +32,56 @@ import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* A {@link Loader} for processing UNIX-style A.out executables
|
||||
*
|
||||
* This style was also used by UNIX-like systems such as SunOS, BSD, and
|
||||
* VxWorks, as well as some early distributions of Linux. Although there do
|
||||
* exist implementations of A.out with 64-bit and GNU extensions, this loader
|
||||
* does not currently support them.
|
||||
* <p>
|
||||
* This style was also used by UNIX-like systems such as SunOS, BSD, and VxWorks, as well as some
|
||||
* early distributions of Linux. Although there do exist implementations of A.out with 64-bit and \
|
||||
* GNU extensions, this loader does not currently support them.
|
||||
*
|
||||
* @see <a href="https://wiki.osdev.org/A.out">OSDev.org A.out</a>
|
||||
* @see <a href="https://man.freebsd.org/cgi/man.cgi?a.out(5)">FreeBSD
|
||||
* manpage</a>
|
||||
* @see <a href="https://man.freebsd.org/cgi/man.cgi?a.out(5)">FreeBSD manpage</a>
|
||||
*/
|
||||
public class UnixAoutLoader extends AbstractProgramWrapperLoader {
|
||||
|
||||
public final static String UNIX_AOUT_NAME = "UNIX A.out";
|
||||
|
||||
public static final String OPTION_NAME_BASE_ADDR = "Base Address";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "UNIX A.out executable";
|
||||
public Collection<LoadSpec> findSupportedLoadSpecs(ByteProvider provider) throws IOException {
|
||||
List<LoadSpec> loadSpecs = new ArrayList<>();
|
||||
|
||||
// Attempt to parse the header as both little- and big-endian.
|
||||
// It is likely that only one of these will produce sensible values.
|
||||
UnixAoutHeader hdrBE = new UnixAoutHeader(provider, false);
|
||||
UnixAoutHeader hdrLE = new UnixAoutHeader(provider, true);
|
||||
boolean beValid = false;
|
||||
|
||||
if (hdrBE.isValid()) {
|
||||
final String lang = hdrBE.getLanguageSpec();
|
||||
final String comp = hdrBE.getCompilerSpec();
|
||||
loadSpecs.add(new LoadSpec(this, 0, new LanguageCompilerSpecPair(lang, comp), true));
|
||||
beValid = true;
|
||||
}
|
||||
if (hdrLE.isValid()) {
|
||||
final String lang = hdrLE.getLanguageSpec();
|
||||
final String comp = hdrLE.getCompilerSpec();
|
||||
loadSpecs
|
||||
.add(new LoadSpec(this, 0, new LanguageCompilerSpecPair(lang, comp), !beValid));
|
||||
}
|
||||
|
||||
return loadSpecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Address offset given in the "Base Address" option.
|
||||
* Returns 0 if the option could not be found or contains an invalid value.
|
||||
*/
|
||||
private long getBaseAddrOffset(List<Option> options) {
|
||||
Address baseAddr = null;
|
||||
|
||||
if (options != null) {
|
||||
for (Option option : options) {
|
||||
String optName = option.getName();
|
||||
if (optName.equals(OPTION_NAME_BASE_ADDR)) {
|
||||
baseAddr = (Address) option.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
|
||||
Program program, TaskMonitor monitor, MessageLog log)
|
||||
throws CancelledException, IOException {
|
||||
final boolean isLittleEndian = !program.getLanguage().isBigEndian();
|
||||
final UnixAoutHeader header = new UnixAoutHeader(provider, isLittleEndian);
|
||||
|
||||
long offset = 0;
|
||||
if (baseAddr != null) {
|
||||
offset = baseAddr.getOffset();
|
||||
}
|
||||
|
||||
return offset;
|
||||
final UnixAoutProgramLoader loader =
|
||||
new UnixAoutProgramLoader(program, header, monitor, log);
|
||||
loader.loadAout(getBaseAddrOffset(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,7 +95,8 @@ public class UnixAoutLoader extends AbstractProgramWrapperLoader {
|
||||
if (optName.equals(OPTION_NAME_BASE_ADDR)) {
|
||||
baseAddr = (Address) option.getValue();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (e instanceof OptionException) {
|
||||
return e.getMessage();
|
||||
}
|
||||
@@ -121,45 +128,38 @@ public class UnixAoutLoader extends AbstractProgramWrapperLoader {
|
||||
|
||||
List<Option> list = new ArrayList<Option>();
|
||||
list.add(new Option(OPTION_NAME_BASE_ADDR, baseAddr, Address.class,
|
||||
Loader.COMMAND_LINE_ARG_PREFIX + "-baseAddr"));
|
||||
Loader.COMMAND_LINE_ARG_PREFIX + "-baseAddr"));
|
||||
|
||||
list.addAll(super.getDefaultOptions(provider, loadSpec, domainObject, loadIntoProgram));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<LoadSpec> findSupportedLoadSpecs(ByteProvider provider) throws IOException {
|
||||
List<LoadSpec> loadSpecs = new ArrayList<>();
|
||||
|
||||
// Attempt to parse the header as both little- and big-endian.
|
||||
// It is likely that only one of these will produce sensible values.
|
||||
UnixAoutHeader hdrBE = new UnixAoutHeader(provider, false);
|
||||
UnixAoutHeader hdrLE = new UnixAoutHeader(provider, true);
|
||||
boolean beValid = false;
|
||||
|
||||
if (hdrBE.isValid()) {
|
||||
final String lang = hdrBE.getLanguageSpec();
|
||||
final String comp = hdrBE.getCompilerSpec();
|
||||
loadSpecs.add(new LoadSpec(this, 0, new LanguageCompilerSpecPair(lang, comp), true));
|
||||
beValid = true;
|
||||
}
|
||||
if (hdrLE.isValid()) {
|
||||
final String lang = hdrLE.getLanguageSpec();
|
||||
final String comp = hdrLE.getCompilerSpec();
|
||||
loadSpecs.add(new LoadSpec(this, 0, new LanguageCompilerSpecPair(lang, comp), !beValid));
|
||||
}
|
||||
|
||||
return loadSpecs;
|
||||
public String getName() {
|
||||
return UNIX_AOUT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
|
||||
Program program, TaskMonitor monitor, MessageLog log)
|
||||
throws CancelledException, IOException {
|
||||
final boolean isLittleEndian = !program.getLanguage().isBigEndian();
|
||||
final UnixAoutHeader header = new UnixAoutHeader(provider, isLittleEndian);
|
||||
/**
|
||||
* Retrieves the Address offset given in the "Base Address" option.
|
||||
* Returns 0 if the option could not be found or contains an invalid value.
|
||||
*/
|
||||
private long getBaseAddrOffset(List<Option> options) {
|
||||
Address baseAddr = null;
|
||||
|
||||
final UnixAoutProgramLoader loader = new UnixAoutProgramLoader(program, header, monitor, log);
|
||||
loader.loadAout(getBaseAddrOffset(options));
|
||||
if (options != null) {
|
||||
for (Option option : options) {
|
||||
String optName = option.getName();
|
||||
if (optName.equals(OPTION_NAME_BASE_ADDR)) {
|
||||
baseAddr = (Address) option.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long offset = 0;
|
||||
if (baseAddr != null) {
|
||||
offset = baseAddr.getOffset();
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
+99
-102
@@ -17,48 +17,28 @@ package ghidra.app.util.opinion;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.util.MemoryBlockUtils;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.bin.format.MemoryLoadable;
|
||||
import ghidra.app.util.bin.format.unixaout.UnixAoutHeader;
|
||||
import ghidra.app.util.bin.format.unixaout.UnixAoutRelocation;
|
||||
import ghidra.app.util.bin.format.unixaout.UnixAoutRelocationTable;
|
||||
import ghidra.app.util.bin.format.unixaout.UnixAoutStringTable;
|
||||
import ghidra.app.util.bin.format.unixaout.UnixAoutSymbol;
|
||||
import ghidra.app.util.bin.format.unixaout.UnixAoutSymbolTable;
|
||||
import ghidra.app.util.bin.format.unixaout.*;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.program.database.function.OverlappingFunctionException;
|
||||
import ghidra.program.database.mem.FileBytes;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressOverflowException;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.reloc.Relocation.Status;
|
||||
import ghidra.program.model.reloc.RelocationTable;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolIterator;
|
||||
import ghidra.program.model.symbol.SymbolTable;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.DataConverter;
|
||||
import ghidra.util.MonitoredInputStream;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
private final static String BLOCK_SOURCE_NAME = "Unix Aout Loader";
|
||||
public class UnixAoutProgramLoader {
|
||||
private final int EXTERNAL_BLOCK_MIN_SIZE = 0x10000; // 64K
|
||||
|
||||
public final static String dot_text = ".text";
|
||||
@@ -69,6 +49,7 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
public final static String dot_strtab = ".strtab";
|
||||
public final static String dot_symtab = ".symtab";
|
||||
|
||||
private final Program program;
|
||||
private final TaskMonitor monitor;
|
||||
private final MessageLog log;
|
||||
private final UnixAoutHeader header;
|
||||
@@ -84,16 +65,17 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
private int extraBssSize = 0;
|
||||
private int undefinedSymbolCount = 0;
|
||||
|
||||
public UnixAoutProgramLoader(Program program, UnixAoutHeader header, TaskMonitor monitor, MessageLog log) {
|
||||
super(program);
|
||||
|
||||
public UnixAoutProgramLoader(Program program, UnixAoutHeader header, TaskMonitor monitor,
|
||||
MessageLog log) {
|
||||
this.program = program;
|
||||
this.monitor = monitor;
|
||||
this.log = log;
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public void loadAout(long baseAddr) throws IOException, CancelledException {
|
||||
log.appendMsg(String.format("----- Loading %s -----", header.getReader().getByteProvider().getAbsolutePath()));
|
||||
log.appendMsg(String.format("----- Loading %s -----",
|
||||
header.getReader().getByteProvider().getAbsolutePath()));
|
||||
log.appendMsg(String.format("Found a.out type %s.", header.getExecutableType().name()));
|
||||
|
||||
ByteProvider byteProvider = header.getReader().getByteProvider();
|
||||
@@ -106,7 +88,9 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
applyRelocations(baseAddr, program.getMemory().getBlock(dot_text), relText);
|
||||
applyRelocations(baseAddr, program.getMemory().getBlock(dot_data), relData);
|
||||
markupSections();
|
||||
} catch (AddressOverflowException | InvalidInputException | CodeUnitInsertionException | DuplicateNameException
|
||||
}
|
||||
catch (AddressOverflowException | InvalidInputException | CodeUnitInsertionException
|
||||
| DuplicateNameException
|
||||
| MemoryAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -114,19 +98,21 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
|
||||
private void buildTables(ByteProvider byteProvider) throws IOException {
|
||||
if (header.getStrSize() > 0) {
|
||||
strtab = new UnixAoutStringTable(header.getReader(), header.getStrOffset(), header.getStrSize());
|
||||
strtab = new UnixAoutStringTable(header.getReader(), header.getStrOffset(),
|
||||
header.getStrSize());
|
||||
}
|
||||
if (header.getSymSize() > 0) {
|
||||
symtab = new UnixAoutSymbolTable(header.getReader(), header.getSymOffset(), header.getSymSize(),
|
||||
strtab, log);
|
||||
symtab = new UnixAoutSymbolTable(header.getReader(), header.getSymOffset(),
|
||||
header.getSymSize(),
|
||||
strtab, log);
|
||||
}
|
||||
if (header.getTextRelocSize() > 0) {
|
||||
relText = new UnixAoutRelocationTable(header.getReader(), header.getTextRelocOffset(),
|
||||
header.getTextRelocSize(), symtab);
|
||||
header.getTextRelocSize(), symtab);
|
||||
}
|
||||
if (header.getDataRelocSize() > 0) {
|
||||
relData = new UnixAoutRelocationTable(header.getReader(), header.getDataRelocOffset(),
|
||||
header.getDataRelocSize(), symtab);
|
||||
header.getDataRelocSize(), symtab);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +131,8 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
// marked as N_UNDF but has a non-zero value means that its value should be
|
||||
// interpreted as a size, and the linker should reserve space in .bss for it.
|
||||
possibleBssSymbols.put(symbol.name, symbol.value);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
undefinedSymbolCount++;
|
||||
}
|
||||
break;
|
||||
@@ -165,7 +152,8 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
}
|
||||
|
||||
if (extraBssSize > 0) {
|
||||
log.appendMsg(dot_bss, String.format("Added %d bytes for N_UNDF symbols.", extraBssSize));
|
||||
log.appendMsg(dot_bss,
|
||||
String.format("Added %d bytes for N_UNDF symbols.", extraBssSize));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,62 +165,71 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
MonitoredInputStream mis = new MonitoredInputStream(fileIn, monitor)) {
|
||||
// Indicate that cleanup is not neccessary for cancelled import operation.
|
||||
mis.setCleanupOnCancel(false);
|
||||
fileBytes = program.getMemory().createFileBytes(byteProvider.getName(), 0, byteProvider.length(), mis,
|
||||
monitor);
|
||||
fileBytes = program.getMemory()
|
||||
.createFileBytes(byteProvider.getName(), 0, byteProvider.length(), mis,
|
||||
monitor);
|
||||
}
|
||||
|
||||
final AddressSpace defaultAddressSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
final AddressSpace defaultAddressSpace =
|
||||
program.getAddressFactory().getDefaultAddressSpace();
|
||||
final Address otherAddress = AddressSpace.OTHER_SPACE.getMinAddress();
|
||||
Address address;
|
||||
Address nextFreeAddress = defaultAddressSpace.getAddress(0);
|
||||
|
||||
if (header.getTextOffset() != 0 || header.getTextSize() < 32) {
|
||||
addInitializedMemorySection(null, 0, 32, otherAddress, "_aoutHeader", false, false, false, null, false,
|
||||
false);
|
||||
MemoryBlockUtils.createInitializedBlock(program, true, "_aoutHeader", otherAddress,
|
||||
fileBytes, 0, 32, null, null, false, false, false, log);
|
||||
}
|
||||
if (header.getTextSize() > 0) {
|
||||
address = defaultAddressSpace.getAddress(baseAddr + header.getTextAddr());
|
||||
nextFreeAddress = address.add(header.getTextSize());
|
||||
addInitializedMemorySection(null, header.getTextOffset(), header.getTextSize(), address, dot_text, true,
|
||||
true, true, null, false, true);
|
||||
MemoryBlockUtils.createInitializedBlock(program, false, dot_text, address, fileBytes,
|
||||
header.getTextOffset(), header.getTextSize(), null, null, true, true, true, log);
|
||||
}
|
||||
if (header.getDataSize() > 0) {
|
||||
address = defaultAddressSpace.getAddress(baseAddr + header.getDataAddr());
|
||||
nextFreeAddress = address.add(header.getDataSize());
|
||||
addInitializedMemorySection(null, header.getDataOffset(), header.getDataSize(), address, dot_data, true,
|
||||
true, false, null, false, true);
|
||||
MemoryBlockUtils.createInitializedBlock(program, false, dot_data, address, fileBytes,
|
||||
header.getDataOffset(), header.getDataSize(), null, null, true, true, false, log);
|
||||
}
|
||||
if ((header.getBssSize() + extraBssSize) > 0) {
|
||||
address = defaultAddressSpace.getAddress(baseAddr + header.getBssAddr());
|
||||
nextFreeAddress = address.add(header.getBssSize() + extraBssSize);
|
||||
addUninitializedMemorySection(null, header.getBssSize() + extraBssSize, address, dot_bss, true, true, false,
|
||||
null, false);
|
||||
MemoryBlockUtils.createUninitializedBlock(program, false, dot_bss, address,
|
||||
header.getBssSize() + extraBssSize, null, null, true, true, false, log);
|
||||
}
|
||||
if (undefinedSymbolCount > 0) {
|
||||
int externalSectionSize = undefinedSymbolCount * 4;
|
||||
if (externalSectionSize < EXTERNAL_BLOCK_MIN_SIZE) {
|
||||
externalSectionSize = EXTERNAL_BLOCK_MIN_SIZE;
|
||||
}
|
||||
addUninitializedMemorySection(null, externalSectionSize, nextFreeAddress, MemoryBlock.EXTERNAL_BLOCK_NAME, false, false, false, "NOTE: This block is artificial and is used to make relocations work correctly", false);
|
||||
MemoryBlock externalBlock = MemoryBlockUtils.createUninitializedBlock(program, false,
|
||||
MemoryBlock.EXTERNAL_BLOCK_NAME, nextFreeAddress, externalSectionSize, null, null,
|
||||
false, false, false, log);
|
||||
if (externalBlock != null) {
|
||||
externalBlock.setArtificial(true);
|
||||
}
|
||||
}
|
||||
if (header.getStrSize() > 0) {
|
||||
addInitializedMemorySection(null, header.getStrOffset(), header.getStrSize(), otherAddress, dot_strtab,
|
||||
false, false, false, null, false, false);
|
||||
MemoryBlockUtils.createInitializedBlock(program, true, dot_strtab, otherAddress,
|
||||
fileBytes, header.getStrOffset(), header.getStrSize(), null, null, false, false,
|
||||
false, log);
|
||||
}
|
||||
if (header.getSymSize() > 0) {
|
||||
addInitializedMemorySection(null, header.getSymOffset(), header.getSymSize(), otherAddress, dot_symtab,
|
||||
false, false, false, null, false, false);
|
||||
MemoryBlockUtils.createInitializedBlock(program, true, dot_symtab, otherAddress,
|
||||
fileBytes, header.getSymOffset(), header.getSymSize(), null, null, false, false,
|
||||
false, log);
|
||||
}
|
||||
if (header.getTextRelocSize() > 0) {
|
||||
addInitializedMemorySection(null, header.getTextRelocOffset(), header.getTextRelocSize(), otherAddress,
|
||||
dot_rel_text, false, false, false, null, false, false);
|
||||
MemoryBlockUtils.createInitializedBlock(program, true, dot_rel_text, otherAddress,
|
||||
fileBytes, header.getTextRelocOffset(), header.getTextRelocSize(), null, null,
|
||||
false, false, false, log);
|
||||
}
|
||||
if (header.getDataRelocSize() > 0) {
|
||||
addInitializedMemorySection(null, header.getDataRelocOffset(), header.getDataRelocSize(), otherAddress,
|
||||
dot_rel_data, false, false, false, null, false, false);
|
||||
MemoryBlockUtils.createInitializedBlock(program, true, dot_rel_data, otherAddress,
|
||||
fileBytes, header.getDataRelocOffset(), header.getDataRelocSize(), null, null,
|
||||
false, false, false, log);
|
||||
}
|
||||
|
||||
resolve(monitor);
|
||||
}
|
||||
|
||||
private void loadSymbols() throws InvalidInputException {
|
||||
@@ -275,7 +272,8 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
address = bssBlock.getEnd().add(extraBssOffset);
|
||||
block = bssBlock;
|
||||
extraBssOffset += symbol.value;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
address = externalBlock.getStart().add(undefinedSymbolIdx++ * 4);
|
||||
block = externalBlock;
|
||||
symbolTable.addExternalEntryPoint(address);
|
||||
@@ -299,16 +297,20 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
switch (symbol.kind) {
|
||||
case AUX_FUNC:
|
||||
try {
|
||||
functionManager.createFunction(symbol.name, address, new AddressSet(address),
|
||||
SourceType.IMPORTED);
|
||||
} catch (OverlappingFunctionException e) {
|
||||
functionManager.createFunction(symbol.name, address,
|
||||
new AddressSet(address),
|
||||
SourceType.IMPORTED);
|
||||
}
|
||||
catch (OverlappingFunctionException e) {
|
||||
log.appendMsg(block.getName(), String.format(
|
||||
"Failed to create function %s @ %s, creating symbol instead.", symbol.name, address));
|
||||
"Failed to create function %s @ %s, creating symbol instead.",
|
||||
symbol.name, address));
|
||||
symbolTable.createLabel(address, symbol.name, SourceType.IMPORTED);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Symbol label = symbolTable.createLabel(address, symbol.name, SourceType.IMPORTED);
|
||||
Symbol label =
|
||||
symbolTable.createLabel(address, symbol.name, SourceType.IMPORTED);
|
||||
if (symbol.isExt) {
|
||||
label.setPrimary();
|
||||
}
|
||||
@@ -323,13 +325,14 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private void applyRelocations(long baseAddr, MemoryBlock targetBlock, UnixAoutRelocationTable relTable)
|
||||
throws MemoryAccessException {
|
||||
private void applyRelocations(long baseAddr, MemoryBlock targetBlock,
|
||||
UnixAoutRelocationTable relTable) throws MemoryAccessException {
|
||||
if (targetBlock == null || relTable == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
monitor.setMessage(String.format("Applying relocations for section %s...", targetBlock.getName()));
|
||||
monitor.setMessage(
|
||||
String.format("Applying relocations for section %s...", targetBlock.getName()));
|
||||
|
||||
DataConverter dc = DataConverter.getInstance(program.getLanguage().isBigEndian());
|
||||
SymbolTable symbolTable = program.getSymbolTable();
|
||||
@@ -350,15 +353,19 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
Long value = null;
|
||||
Status status = Status.FAILURE;
|
||||
|
||||
if (relocation.baseRelative || relocation.jmpTable || relocation.relative || relocation.copy) {
|
||||
if (relocation.baseRelative || relocation.jmpTable || relocation.relative ||
|
||||
relocation.copy) {
|
||||
status = Status.UNSUPPORTED;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (relocation.extern == true && relocation.symbolNum < symtab.size()) {
|
||||
SymbolIterator symbolIterator = symbolTable.getSymbols(symtab.get(relocation.symbolNum).name);
|
||||
SymbolIterator symbolIterator =
|
||||
symbolTable.getSymbols(symtab.get(relocation.symbolNum).name);
|
||||
if (symbolIterator.hasNext()) {
|
||||
value = symbolIterator.next().getAddress().getOffset();
|
||||
}
|
||||
} else if (relocation.extern == false) {
|
||||
}
|
||||
else if (relocation.extern == false) {
|
||||
switch (relocation.symbolNum) {
|
||||
case 4:
|
||||
value = textBlock.getStart().getOffset();
|
||||
@@ -389,19 +396,21 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
|
||||
if (status != Status.APPLIED) {
|
||||
log.appendMsg(targetBlock.getName(),
|
||||
String.format("Failed to apply relocation entry %d with type 0x%02x @ %s.", idx,
|
||||
relocation.flags, targetAddress));
|
||||
String.format("Failed to apply relocation entry %d with type 0x%02x @ %s.", idx,
|
||||
relocation.flags, targetAddress));
|
||||
}
|
||||
|
||||
relocationTable.add(targetAddress, status, relocation.flags, new long[] { relocation.symbolNum },
|
||||
originalBytes, relocation.getSymbolName(symtab));
|
||||
relocationTable.add(targetAddress, status, relocation.flags,
|
||||
new long[] { relocation.symbolNum },
|
||||
originalBytes, relocation.getSymbolName(symtab));
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
private void markupSections()
|
||||
throws InvalidInputException, CodeUnitInsertionException, DuplicateNameException, IOException {
|
||||
final AddressSpace defaultAddressSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
private void markupSections() throws InvalidInputException, CodeUnitInsertionException,
|
||||
DuplicateNameException, IOException {
|
||||
final AddressSpace defaultAddressSpace =
|
||||
program.getAddressFactory().getDefaultAddressSpace();
|
||||
final FunctionManager functionManager = program.getFunctionManager();
|
||||
final SymbolTable symbolTable = program.getSymbolTable();
|
||||
|
||||
@@ -413,7 +422,8 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
MemoryBlock textBlock = program.getMemory().getBlock(dot_text);
|
||||
if (aoutHeader != null) {
|
||||
headerAddress = aoutHeader.getStart();
|
||||
} else if (textBlock != null && header.getTextOffset() == 0 && header.getTextSize() >= 32) {
|
||||
}
|
||||
else if (textBlock != null && header.getTextOffset() == 0 && header.getTextSize() >= 32) {
|
||||
headerAddress = textBlock.getStart();
|
||||
}
|
||||
if (headerAddress != null) {
|
||||
@@ -424,9 +434,12 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
if (header.getEntryPoint() != 0) {
|
||||
Address address = defaultAddressSpace.getAddress(header.getEntryPoint());
|
||||
try {
|
||||
functionManager.createFunction("entry", address, new AddressSet(address), SourceType.IMPORTED);
|
||||
} catch (OverlappingFunctionException e) {
|
||||
log.appendMsg(dot_text, "Failed to create entrypoint function @ %s, creating symbol instead.");
|
||||
functionManager.createFunction("entry", address, new AddressSet(address),
|
||||
SourceType.IMPORTED);
|
||||
}
|
||||
catch (OverlappingFunctionException e) {
|
||||
log.appendMsg(dot_text,
|
||||
"Failed to create entrypoint function @ %s, creating symbol instead.");
|
||||
symbolTable.createLabel(address, "entry", SourceType.IMPORTED);
|
||||
}
|
||||
}
|
||||
@@ -457,20 +470,4 @@ public class UnixAoutProgramLoader extends MemorySectionResolver {
|
||||
strtab.markup(program, strtabBlock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemoryBlock createInitializedBlock(MemoryLoadable key, boolean isOverlay, String name, Address start,
|
||||
long fileOffset, long length, String comment, boolean r, boolean w, boolean x, TaskMonitor monitor)
|
||||
throws IOException, AddressOverflowException, CancelledException {
|
||||
return MemoryBlockUtils.createInitializedBlock(program, isOverlay, name, start, fileBytes, fileOffset, length,
|
||||
comment, BLOCK_SOURCE_NAME, r, w, x, log);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemoryBlock createUninitializedBlock(MemoryLoadable key, boolean isOverlay, String name, Address start,
|
||||
long length, String comment, boolean r, boolean w, boolean x)
|
||||
throws IOException, AddressOverflowException, CancelledException {
|
||||
return MemoryBlockUtils.createUninitializedBlock(program, isOverlay, name, start, length, comment, comment, r,
|
||||
w, x, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user