mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
aa333c1d2f
8 changed files with 154 additions and 98 deletions
|
@ -36,7 +36,7 @@ public class ObjectiveC2_Method extends ObjectiveC_Method {
|
|||
isSmall = isSmallList;
|
||||
|
||||
if (isSmallList) {
|
||||
int nameOffset = (int)ObjectiveC1_Utilities.readNextIndex(reader, true);
|
||||
int nameOffset = (int) ObjectiveC1_Utilities.readNextIndex(reader, true);
|
||||
long namePtr;
|
||||
if (state.is32bit) {
|
||||
namePtr = reader.readInt(_index + nameOffset);
|
||||
|
@ -47,17 +47,17 @@ public class ObjectiveC2_Method extends ObjectiveC_Method {
|
|||
|
||||
name = reader.readAsciiString(namePtr);
|
||||
|
||||
int typesOffset = (int)ObjectiveC1_Utilities.readNextIndex(reader, true);
|
||||
int typesOffset = (int) ObjectiveC1_Utilities.readNextIndex(reader, true);
|
||||
types = reader.readAsciiString(_index + 4 + typesOffset);
|
||||
}
|
||||
else {
|
||||
long nameIndex = ObjectiveC1_Utilities.readNextIndex(reader, state.is32bit);
|
||||
name = reader.readAsciiString(nameIndex);
|
||||
name = reader.readAsciiString(nameIndex);
|
||||
|
||||
long typesIndex = ObjectiveC1_Utilities.readNextIndex(reader, state.is32bit);
|
||||
types = reader.readAsciiString(typesIndex);
|
||||
}
|
||||
|
||||
|
||||
imp = new ObjectiveC2_Implementation(state, reader, isSmallList);
|
||||
}
|
||||
|
||||
|
@ -65,17 +65,20 @@ public class ObjectiveC2_Method extends ObjectiveC_Method {
|
|||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getImplementation() {
|
||||
return imp.getImplementation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
Structure struct = new StructureDataType("method_t", 0);
|
||||
Structure struct = new StructureDataType("method" + (isSmall ? "_small" : "") + "_t", 0);
|
||||
if (isSmall) {
|
||||
DataType sdw = SignedDWordDataType.dataType;
|
||||
String comment = "offset from this address";
|
||||
|
@ -84,9 +87,9 @@ public class ObjectiveC2_Method extends ObjectiveC_Method {
|
|||
struct.add(sdw, sdw.getLength(), "imp", comment);
|
||||
}
|
||||
else {
|
||||
struct.add(new PointerDataType(STRING), _state.pointerSize, "name", null);
|
||||
struct.add(new PointerDataType(STRING), _state.pointerSize, "name", null);
|
||||
struct.add(new PointerDataType(STRING), _state.pointerSize, "types", null);
|
||||
struct.add(new PointerDataType(VOID), _state.pointerSize, "imp", null);
|
||||
struct.add(new PointerDataType(VOID), _state.pointerSize, "imp", null);
|
||||
}
|
||||
struct.setCategoryPath(ObjectiveC2_Constants.CATEGORY_PATH);
|
||||
return struct;
|
||||
|
|
|
@ -29,7 +29,8 @@ public class ObjectiveC2_MethodList extends ObjectiveC_MethodList {
|
|||
private int entsizeAndFlags;
|
||||
private int count;
|
||||
|
||||
public ObjectiveC2_MethodList(ObjectiveC2_State state, BinaryReader reader, ObjectiveC_MethodType methodType) throws IOException {
|
||||
public ObjectiveC2_MethodList(ObjectiveC2_State state, BinaryReader reader,
|
||||
ObjectiveC_MethodType methodType) throws IOException {
|
||||
super(state, reader, NAME);
|
||||
|
||||
if (_index == 0) {
|
||||
|
@ -37,15 +38,19 @@ public class ObjectiveC2_MethodList extends ObjectiveC_MethodList {
|
|||
}
|
||||
|
||||
entsizeAndFlags = reader.readNextInt();
|
||||
count = reader.readNextInt();
|
||||
count = reader.readNextInt();
|
||||
|
||||
boolean isSmallList = (entsizeAndFlags & 0x80000000) != 0;
|
||||
boolean isSmallList = isSmallMethods();
|
||||
|
||||
for (int i = 0 ; i < count ; ++i) {
|
||||
methods.add( new ObjectiveC2_Method(state, reader, methodType, isSmallList) );
|
||||
for (int i = 0; i < count; ++i) {
|
||||
methods.add(new ObjectiveC2_Method(state, reader, methodType, isSmallList));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isSmallMethods() {
|
||||
return (entsizeAndFlags & 0x80000000) != 0;
|
||||
}
|
||||
|
||||
public long getEntsizeAndFlags() {
|
||||
return entsizeAndFlags;
|
||||
}
|
||||
|
@ -57,19 +62,21 @@ public class ObjectiveC2_MethodList extends ObjectiveC_MethodList {
|
|||
public static DataType toGenericDataType() throws DuplicateNameException {
|
||||
Structure struct = new StructureDataType(NAME, 0);
|
||||
struct.add(DWORD, "entsizeAndFlags", null);
|
||||
struct.add(DWORD, "count", null);
|
||||
struct.add(DWORD, "count", null);
|
||||
struct.setCategoryPath(ObjectiveC2_Constants.CATEGORY_PATH);
|
||||
return struct;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
Structure struct = new StructureDataType(NAME+'_'+count+'_', 0);
|
||||
Structure struct =
|
||||
new StructureDataType(NAME + (isSmallMethods() ? "_small" : "") + '_' + count + '_', 0);
|
||||
|
||||
struct.add(DWORD, "entsizeAndFlags", null);
|
||||
struct.add(DWORD, "count", null);
|
||||
struct.add(DWORD, "count", null);
|
||||
|
||||
for (int i = 0 ; i < methods.size() ; ++i) {
|
||||
struct.add(methods.get(i).toDataType(), "method"+i, null);
|
||||
for (int i = 0; i < methods.size(); ++i) {
|
||||
struct.add(methods.get(i).toDataType(), "method" + i, null);
|
||||
}
|
||||
|
||||
struct.setCategoryPath(ObjectiveC2_Constants.CATEGORY_PATH);
|
||||
|
|
|
@ -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.
|
||||
|
@ -16,14 +15,16 @@
|
|||
*/
|
||||
package ghidra.app.util.bin.format.objectiveC;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataUtilities.ClearDataMode;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ObjectiveC1_Module implements StructConverter {
|
||||
private ObjectiveC1_State _state;
|
||||
private long _index;
|
||||
|
@ -74,9 +75,11 @@ public class ObjectiveC1_Module implements StructConverter {
|
|||
_state.program.getAddressFactory().getDefaultAddressSpace().getAddress(_index);
|
||||
DataType dt = toDataType();
|
||||
try {
|
||||
_state.program.getListing().createData(address, dt);
|
||||
DataUtilities.createData(_state.program, address, dt, -1, false,
|
||||
ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.warn(this, "Could not create " + dt.getName() + " @" + address);
|
||||
}
|
||||
|
||||
if (symbolTable != null) {
|
||||
|
@ -84,6 +87,7 @@ public class ObjectiveC1_Module implements StructConverter {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType("objc_module", 0);
|
||||
struct.setCategoryPath(ObjectiveC1_Constants.CATEGORY_PATH);
|
||||
|
|
|
@ -23,6 +23,8 @@ import ghidra.app.util.bin.BinaryReader;
|
|||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataUtilities.ClearDataMode;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
public class ObjectiveC1_SymbolTable implements StructConverter {
|
||||
|
@ -42,12 +44,12 @@ public class ObjectiveC1_SymbolTable implements StructConverter {
|
|||
this._state = state;
|
||||
this._index = reader.getPointerIndex();
|
||||
|
||||
sel_ref_cnt = reader.readNextInt();
|
||||
refs = reader.readNextInt();
|
||||
cls_def_cnt = reader.readNextShort();
|
||||
cat_def_cnt = reader.readNextShort();
|
||||
sel_ref_cnt = reader.readNextInt();
|
||||
refs = reader.readNextInt();
|
||||
cls_def_cnt = reader.readNextShort();
|
||||
cat_def_cnt = reader.readNextShort();
|
||||
|
||||
for (int i = 0 ; i < cls_def_cnt ; ++i) {
|
||||
for (int i = 0; i < cls_def_cnt; ++i) {
|
||||
long classIndex = reader.readNextInt();
|
||||
long oldClassIndex = reader.getPointerIndex();
|
||||
reader.setPointerIndex(classIndex);
|
||||
|
@ -55,7 +57,7 @@ public class ObjectiveC1_SymbolTable implements StructConverter {
|
|||
reader.setPointerIndex(oldClassIndex);
|
||||
}
|
||||
|
||||
for (int i = 0 ; i < cat_def_cnt ; ++i) {
|
||||
for (int i = 0; i < cat_def_cnt; ++i) {
|
||||
long categoryIndex = reader.readNextInt();
|
||||
long oldCategoryIndex = reader.getPointerIndex();
|
||||
reader.setPointerIndex(categoryIndex);
|
||||
|
@ -67,12 +69,15 @@ public class ObjectiveC1_SymbolTable implements StructConverter {
|
|||
public int getSelectorReferenceCount() {
|
||||
return sel_ref_cnt;
|
||||
}
|
||||
|
||||
public int getRefs() {
|
||||
return refs;
|
||||
}
|
||||
|
||||
public short getClassDefinitionCount() {
|
||||
return cls_def_cnt;
|
||||
}
|
||||
|
||||
public short getCategoryDefinitionCount() {
|
||||
return cat_def_cnt;
|
||||
}
|
||||
|
@ -80,6 +85,7 @@ public class ObjectiveC1_SymbolTable implements StructConverter {
|
|||
public List<ObjectiveC1_Class> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
public List<ObjectiveC1_Category> getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
@ -89,23 +95,28 @@ public class ObjectiveC1_SymbolTable implements StructConverter {
|
|||
struct.setCategoryPath(ObjectiveC1_Constants.CATEGORY_PATH);
|
||||
struct.add(DWORD, "sel_ref_cnt", null);
|
||||
struct.add(DWORD, "refs", null);
|
||||
struct.add( WORD, "cls_def_cnt", null);
|
||||
struct.add( WORD, "cat_def_cnt", null);
|
||||
struct.add(WORD, "cls_def_cnt", null);
|
||||
struct.add(WORD, "cat_def_cnt", null);
|
||||
return struct;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType(NAME+"_"+cls_def_cnt+"_"+cat_def_cnt+"_", 0);
|
||||
StructureDataType struct =
|
||||
new StructureDataType(NAME + "_" + cls_def_cnt + "_" + cat_def_cnt + "_", 0);
|
||||
struct.setCategoryPath(ObjectiveC1_Constants.CATEGORY_PATH);
|
||||
struct.add(DWORD, "sel_ref_cnt", null);
|
||||
struct.add(DWORD, "refs", null);
|
||||
struct.add( WORD, "cls_def_cnt", null);
|
||||
struct.add( WORD, "cat_def_cnt", null);
|
||||
for (int i = 0 ; i < cls_def_cnt ; ++i) {
|
||||
struct.add(PointerDataType.getPointer(classes.get(i).toDataType(), _state.pointerSize), "class"+i, null);
|
||||
struct.add(WORD, "cls_def_cnt", null);
|
||||
struct.add(WORD, "cat_def_cnt", null);
|
||||
for (int i = 0; i < cls_def_cnt; ++i) {
|
||||
struct.add(PointerDataType.getPointer(classes.get(i).toDataType(), _state.pointerSize),
|
||||
"class" + i, null);
|
||||
}
|
||||
for (int i = 0 ; i < cat_def_cnt ; ++i) {
|
||||
struct.add(PointerDataType.getPointer(categories.get(i).toDataType(), _state.pointerSize), "category"+i, null);
|
||||
for (int i = 0; i < cat_def_cnt; ++i) {
|
||||
struct.add(
|
||||
PointerDataType.getPointer(categories.get(i).toDataType(), _state.pointerSize),
|
||||
"category" + i, null);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
|
@ -116,11 +127,16 @@ public class ObjectiveC1_SymbolTable implements StructConverter {
|
|||
}
|
||||
_state.beenApplied.add(_index);
|
||||
|
||||
Address address = _state.program.getAddressFactory().getDefaultAddressSpace().getAddress(_index);
|
||||
Address address =
|
||||
_state.program.getAddressFactory().getDefaultAddressSpace().getAddress(_index);
|
||||
DataType dt = toDataType();
|
||||
try {
|
||||
_state.program.getListing().createData(address, toDataType());
|
||||
DataUtilities.createData(_state.program, address, dt, -1, false,
|
||||
ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.warn(this, "Could not create " + dt.getName() + " @" + address);
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
_state.program.getListing().getDefinedDataAt(address);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import ghidra.framework.cmd.Command;
|
|||
import ghidra.program.database.symbol.ClassSymbol;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataUtilities.ClearDataMode;
|
||||
import ghidra.program.model.lang.Processor;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.*;
|
||||
|
@ -48,8 +49,8 @@ public final class ObjectiveC1_Utilities {
|
|||
* Clears the code units defined in the given memory block.
|
||||
*/
|
||||
public static void clear(ObjectiveC2_State state, MemoryBlock block) throws Exception {
|
||||
state.program.getListing().clearCodeUnits(block.getStart(), block.getEnd(), false,
|
||||
state.monitor);
|
||||
state.program.getListing()
|
||||
.clearCodeUnits(block.getStart(), block.getEnd(), false, state.monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,9 +144,11 @@ public final class ObjectiveC1_Utilities {
|
|||
if (data != null && data.getDataType().isEquivalent(dt)) {
|
||||
return;
|
||||
}
|
||||
//program.getListing().clearCodeUnits(address, address.add(dt.getLength()-1));
|
||||
|
||||
program.getListing().createData(address, dt);
|
||||
// need to clear, as pointers could have been created on import
|
||||
// from following pointer chains
|
||||
DataUtilities.createData(program, address, dt, -1, false,
|
||||
ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,8 +233,8 @@ public final class ObjectiveC1_Utilities {
|
|||
*/
|
||||
public static Symbol createSymbol(Program program, Namespace parentNamespace, String symbolName,
|
||||
Address symbolAddress) throws InvalidInputException {
|
||||
Symbol symbol = program.getSymbolTable().createLabel(symbolAddress, symbolName,
|
||||
parentNamespace, SourceType.IMPORTED);
|
||||
Symbol symbol = program.getSymbolTable()
|
||||
.createLabel(symbolAddress, symbolName, parentNamespace, SourceType.IMPORTED);
|
||||
symbol.setPrimary();
|
||||
return symbol;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -16,13 +15,15 @@
|
|||
*/
|
||||
package ghidra.app.util.bin.format.objectiveC;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public abstract class ObjectiveC_MethodList implements StructConverter {
|
||||
private String _className;
|
||||
|
@ -31,7 +32,8 @@ public abstract class ObjectiveC_MethodList implements StructConverter {
|
|||
|
||||
protected List<ObjectiveC_Method> methods = new ArrayList<ObjectiveC_Method>();
|
||||
|
||||
protected ObjectiveC_MethodList(ObjectiveC1_State state, BinaryReader reader, String className) {
|
||||
protected ObjectiveC_MethodList(ObjectiveC1_State state, BinaryReader reader,
|
||||
String className) {
|
||||
this._state = state;
|
||||
this._index = reader.getPointerIndex();
|
||||
this._className = className;
|
||||
|
@ -51,17 +53,23 @@ public abstract class ObjectiveC_MethodList implements StructConverter {
|
|||
_state.beenApplied.add(_index);
|
||||
|
||||
Address address = ObjectiveC1_Utilities.toAddress(_state.program, _index);
|
||||
DataType dt = toDataType();
|
||||
try {
|
||||
ObjectiveC1_Utilities.applyData(_state.program, toDataType(), address);
|
||||
ObjectiveC1_Utilities.applyData(_state.program, dt, address);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.warn(this, "Could not create " + dt.getName() + " @" + address);
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
try {
|
||||
//creates a symbol on the method list data structure
|
||||
Namespace methodListNamespace = ObjectiveC1_Utilities.createNamespace(_state.program, ObjectiveC1_Constants.NAMESPACE, _className);
|
||||
ObjectiveC1_Utilities.createSymbol(_state.program, methodListNamespace, namespace.getName(), address);
|
||||
Namespace methodListNamespace = ObjectiveC1_Utilities.createNamespace(_state.program,
|
||||
ObjectiveC1_Constants.NAMESPACE, _className);
|
||||
ObjectiveC1_Utilities.createSymbol(_state.program, methodListNamespace,
|
||||
namespace.getName(), address);
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
for (ObjectiveC_Method method : getMethods()) {
|
||||
method.applyTo(namespace);
|
||||
|
|
|
@ -191,6 +191,9 @@ public class ObjectiveC2_DecompilerMessageAnalyzer extends AbstractAnalyzer {
|
|||
}
|
||||
setReference(objcCallAddress, program, currentClassName, currentMethodName);
|
||||
|
||||
if (instruction == null) {
|
||||
return;
|
||||
}
|
||||
if (instruction.getComment(CodeUnit.EOL_COMMENT) != null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -70,21 +70,57 @@ public final class DataUtilities {
|
|||
*/
|
||||
CLEAR_SINGLE_DATA,
|
||||
/**
|
||||
* Clear all conflicting Undefined data provided data will
|
||||
* Clear all conflicting Undefined Data provided new data will
|
||||
* fit within memory and not conflict with an
|
||||
* instruction or other defined data. Undefined refers to defined
|
||||
* data with the Undefined data-type.
|
||||
* @see Undefined#isUndefined(DataType)
|
||||
* data with the Undefined data-type (see {@link Undefined#isUndefined(DataType)}).
|
||||
*/
|
||||
CLEAR_ALL_UNDEFINED_CONFLICT_DATA,
|
||||
/**
|
||||
* Clear all conflicting data provided data will
|
||||
* fit within memory and not conflict with an
|
||||
* instruction.
|
||||
* Clear all Default Data provided new data will fit within memory and
|
||||
* not conflict with an instruction or other defined data. In this
|
||||
* context Default Data refers to all defined data with either an
|
||||
* Undefined data-type (see {@link Undefined#isUndefined(DataType)}) or
|
||||
* is considered a default pointer which is either:
|
||||
* <ol>
|
||||
* <li>A pointer without a referenced datatype (i.e., <i>addr</i>), or</li>
|
||||
* <li>An auto-named pointer-typedef without a referenced datatype
|
||||
* (e.g., <i>pointer __((offset(0x8)))</i>.</li>
|
||||
* </ol>
|
||||
*/
|
||||
CLEAR_ALL_DEFAULT_CONFLICT_DATA,
|
||||
/**
|
||||
* Clear all conflicting data provided new data will fit within memory and
|
||||
* not conflict with an instruction.
|
||||
*/
|
||||
CLEAR_ALL_CONFLICT_DATA
|
||||
}
|
||||
|
||||
private static boolean isDefaultData(DataType dt) {
|
||||
// see ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA
|
||||
if (Undefined.isUndefined(dt)) {
|
||||
return true;
|
||||
}
|
||||
if (dt instanceof Pointer) {
|
||||
Pointer p = (Pointer) dt;
|
||||
dt = p.getDataType();
|
||||
return dt == null || dt == DataType.DEFAULT;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isDataClearingDenied(DataType dt, ClearDataMode clearMode) {
|
||||
if ((clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA &&
|
||||
!Undefined.isUndefined(dt))) {
|
||||
return true;
|
||||
}
|
||||
if (clearMode == ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA &&
|
||||
!isDefaultData(dt)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create data where existing data may already exist.
|
||||
* @param program the program
|
||||
|
@ -113,8 +149,7 @@ public final class DataUtilities {
|
|||
return data;
|
||||
}
|
||||
|
||||
if (!stackPointers && clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA &&
|
||||
!Undefined.isUndefined(existingType)) {
|
||||
if (!stackPointers && isDataClearingDenied(existingType, clearMode)) {
|
||||
throw new CodeUnitInsertionException("Could not create Data at address " + addr);
|
||||
}
|
||||
|
||||
|
@ -176,12 +211,12 @@ public final class DataUtilities {
|
|||
|
||||
// null data; see if we are in a composite
|
||||
if (clearMode == ClearDataMode.CLEAR_ALL_CONFLICT_DATA ||
|
||||
clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA) {
|
||||
clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA ||
|
||||
clearMode == ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA) {
|
||||
|
||||
// allow offcut addr if CLEAR_ALL_CONFLICT_DATA
|
||||
data = listing.getDataContaining(addr);
|
||||
if (data != null && clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA &&
|
||||
!Undefined.isUndefined(data.getDataType())) {
|
||||
if (data != null && isDataClearingDenied(data.getDataType(), clearMode)) {
|
||||
data = null; // force error
|
||||
}
|
||||
}
|
||||
|
@ -267,32 +302,8 @@ public final class DataUtilities {
|
|||
return extRef;
|
||||
}
|
||||
|
||||
private static void validateCanCreateData(Address addr, ClearDataMode clearMode,
|
||||
Listing listing, Data data) throws CodeUnitInsertionException {
|
||||
|
||||
if (data != null) {
|
||||
return; // existing data; it us possible to create data
|
||||
}
|
||||
|
||||
if (clearMode == ClearDataMode.CLEAR_ALL_CONFLICT_DATA ||
|
||||
clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA) {
|
||||
|
||||
// allow offcut addr if CLEAR_ALL_CONFLICT_DATA
|
||||
data = listing.getDataContaining(addr);
|
||||
if (data != null && clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA &&
|
||||
!Undefined.isUndefined(data.getDataType())) {
|
||||
data = null; // force error
|
||||
}
|
||||
}
|
||||
|
||||
// null data implies that we cannot create data at this address
|
||||
if (data == null) {
|
||||
throw new CodeUnitInsertionException("Could not create Data at address " + addr);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkEnoughSpace(Program program, Address addr, int existingDataLen,
|
||||
DataTypeInstance dti, ClearDataMode mode) throws CodeUnitInsertionException {
|
||||
DataTypeInstance dti, ClearDataMode clearMode) throws CodeUnitInsertionException {
|
||||
// NOTE: method not invoked when clearMode == ClearDataMode.CLEAR_SINGLE_DATA
|
||||
Listing listing = program.getListing();
|
||||
Address end = null;
|
||||
|
@ -318,11 +329,12 @@ public final class DataUtilities {
|
|||
return;
|
||||
}
|
||||
|
||||
if (mode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA &&
|
||||
Undefined.isUndefined(definedData.getDataType())) {
|
||||
checkForDefinedData(dti, listing, newEnd, definedData.getMaxAddress());
|
||||
if ((clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA ||
|
||||
clearMode == ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA) &&
|
||||
!isDataClearingDenied(definedData.getDataType(), clearMode)) {
|
||||
checkForDefinedData(dti, listing, newEnd, definedData.getMaxAddress(), clearMode);
|
||||
}
|
||||
else if (mode != ClearDataMode.CLEAR_ALL_CONFLICT_DATA) {
|
||||
else if (clearMode != ClearDataMode.CLEAR_ALL_CONFLICT_DATA) {
|
||||
throw new CodeUnitInsertionException("Not enough space to create DataType " +
|
||||
dti.getDataType().getDisplayName());
|
||||
}
|
||||
|
@ -330,9 +342,9 @@ public final class DataUtilities {
|
|||
}
|
||||
|
||||
private static void checkForDefinedData(DataTypeInstance dti, Listing listing, Address address,
|
||||
Address end) throws CodeUnitInsertionException {
|
||||
Address end, ClearDataMode clearMode) throws CodeUnitInsertionException {
|
||||
|
||||
// ignore all defined data which is considered Undefined and may be cleared
|
||||
// ignore all defined data which may be cleared
|
||||
while (end.compareTo(address) <= 0) {
|
||||
Data definedData = listing.getDefinedDataAfter(end);
|
||||
if (definedData == null ||
|
||||
|
@ -340,7 +352,7 @@ public final class DataUtilities {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!Undefined.isUndefined(definedData.getDataType())) {
|
||||
if (isDataClearingDenied(definedData.getDataType(), clearMode)) {
|
||||
throw new CodeUnitInsertionException("Not enough space to create DataType " +
|
||||
dti.getDataType().getDisplayName());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue