Merge branch 'GP-3383_dev747368_refactor_programcontext_classname' into Ghidra_10.3

This commit is contained in:
ghidra1 2023-05-09 17:09:07 -04:00
commit e8a0323902
29 changed files with 112 additions and 112 deletions

View file

@ -27,7 +27,7 @@ import ghidra.app.util.MemoryBlockUtils;
import ghidra.app.util.bin.format.elf.info.ElfInfoItem.ItemWithAddress;
import ghidra.app.util.bin.format.golang.*;
import ghidra.app.util.bin.format.golang.rtti.GoModuledata;
import ghidra.app.util.bin.format.golang.rtti.GoRttiContext;
import ghidra.app.util.bin.format.golang.rtti.GoRttiMapper;
import ghidra.app.util.importer.MessageLog;
import ghidra.framework.options.Options;
import ghidra.program.model.address.Address;
@ -72,9 +72,9 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
throws CancelledException {
monitor.setMessage("Golang symbol analyzer");
try (GoRttiContext programContext = GoRttiContext.getContextFor(program, log)) {
try (GoRttiMapper programContext = GoRttiMapper.getMapperFor(program, log)) {
if (programContext == null) {
Msg.error(this, "Golang analyzer error: unable to get GoRttiContext");
Msg.error(this, "Golang analyzer error: unable to get GoRttiMapper");
return false;
}
programContext.discoverGoTypes(monitor);
@ -121,7 +121,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
analyzerOptions.createBootstrapDatatypeArchive);
}
private void markupWellknownSymbols(GoRttiContext programContext) throws IOException {
private void markupWellknownSymbols(GoRttiMapper programContext) throws IOException {
Program program = programContext.getProgram();
Symbol g0 = SymbolUtilities.getUniqueSymbol(program, "runtime.g0");
@ -225,7 +225,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
return newMB.getStart();
}
private void setupProgramContext(GoRttiContext programContext) throws IOException {
private void setupProgramContext(GoRttiMapper programContext) throws IOException {
Program program = programContext.getProgram();
GoRegisterInfo goRegInfo = GoRegisterInfoManager.getInstance()
.getRegisterInfoForLang(program.getLanguage(),
@ -299,12 +299,12 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
}
}
private void createBootstrapGDT(GoRttiContext programContext, Program program,
private void createBootstrapGDT(GoRttiMapper programContext, Program program,
TaskMonitor monitor) throws IOException {
GoVer goVer = programContext.getGolangVersion();
String osName = GoRttiContext.getGolangOSString(program);
String osName = GoRttiMapper.getGolangOSString(program);
String gdtFilename =
GoRttiContext.getGDTFilename(goVer, programContext.getPtrSize(), osName);
GoRttiMapper.getGDTFilename(goVer, programContext.getPtrSize(), osName);
gdtFilename =
gdtFilename.replace(".gdt", "_%d.gdt".formatted(System.currentTimeMillis()));
File gdt = new File(System.getProperty("user.home"), gdtFilename);

View file

@ -85,8 +85,7 @@ public class ElfNote implements ElfInfoItem {
* @param program {@link Program}
* @param sectionName name of the note section
* @param readerFunc {@link NoteReaderFunc} that converts a generic note instance into a
* specialized note.<br>
* Example: <code>(note, programContext) -> new MyNote(....)</code>
* specialized note.
* @return new Note instance, or null if not present or error reading
*/
protected static <T extends ElfNote> T readFromProgramHelper(Program program,

View file

@ -33,7 +33,7 @@ import ghidra.util.exception.InvalidInputException;
@StructureMapping(structureName = "runtime._func")
public class GoFuncData implements StructureMarkup<GoFuncData> {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoFuncData> context;

View file

@ -23,7 +23,7 @@ import ghidra.program.model.address.Address;
@StructureMapping(structureName = "runtime.functab")
public class GoFunctabEntry {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoFunctabEntry> context;

View file

@ -22,7 +22,7 @@ import ghidra.app.util.bin.format.golang.structmapping.*;
@StructureMapping(structureName = "runtime.iface")
public class GoIface {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoIface> context;

View file

@ -31,7 +31,7 @@ import ghidra.program.model.data.DataType;
@StructureMapping(structureName = "runtime.itab")
public class GoItab implements StructureMarkup<GoItab> {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoItab> context;

View file

@ -43,7 +43,7 @@ import ghidra.util.task.TaskMonitor;
public class GoModuledata implements StructureMarkup<GoModuledata> {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoModuledata> structureContext;
@ -156,7 +156,7 @@ public class GoModuledata implements StructureMarkup<GoModuledata> {
itablinks.markupArray("moduledata.itablinks", GoItab.class, true);
//cutab.markupArray("moduledata.cutab", programContext.getUint32DT(), false);
//cutab.markupArray("moduledata.cutab", dataTypeMapper.getUint32DT(), false);
markupStringTable(funcnametab.getArrayAddress(), funcnametab.getLen());
markupStringTable(filetab.getArrayAddress(), filetab.getLen());
@ -233,11 +233,11 @@ public class GoModuledata implements StructureMarkup<GoModuledata> {
/**
* Returns an easily found first GoModuledata instance.
*
* @param context already initialized {@link GoRttiContext}
* @param context already initialized {@link GoRttiMapper}
* @return new GoModuledata instance, or null if not found
* @throws IOException
*/
/* package */ static GoModuledata getFirstModuledata(GoRttiContext context)
/* package */ static GoModuledata getFirstModuledata(GoRttiMapper context)
throws IOException {
Program program = context.getProgram();
Symbol firstModuleDataSymbol =
@ -251,7 +251,7 @@ public class GoModuledata implements StructureMarkup<GoModuledata> {
/**
* Searches memory for a likely GoModuledata
*
* @param context already initialized {@link GoRttiContext}
* @param context already initialized {@link GoRttiMapper}
* @param pclntabAddress address of an already found {@link GoPcHeader}
* @param pclntab the {@link GoPcHeader}
* @param range memory range to search. Will be different for different types of binaries
@ -259,7 +259,7 @@ public class GoModuledata implements StructureMarkup<GoModuledata> {
* @return new GoModuledata instance, or null if not found
* @throws IOException
*/
/* package */ static GoModuledata findFirstModule(GoRttiContext context,
/* package */ static GoModuledata findFirstModule(GoRttiMapper context,
Address pclntabAddress, GoPcHeader pclntab, AddressRange range, TaskMonitor monitor)
throws IOException {
if (range == null) {

View file

@ -73,7 +73,7 @@ public class GoName implements StructureReader<GoName>, StructureMarkup<GoName>
private StructureContext<GoName> context;
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@FieldOutput(dataTypeName = "byte")
@EOLComment("flagsSet")

View file

@ -26,7 +26,8 @@ import ghidra.program.model.lang.Endian;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.symbol.*;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolUtilities;
import ghidra.util.task.TaskMonitor;
/**
@ -84,13 +85,13 @@ public class GoPcHeader {
* Searches (possibly slowly) for a pclntab structure in the specified memory range, which
* is typically necessary in stripped PE binaries.
*
* @param programContext {@link GoRttiContext}
* @param programContext {@link GoRttiMapper}
* @param range memory range to search (typically .rdata or .noptrdata sections)
* @param monitor {@link TaskMonitor} that will let the user cancel
* @return {@link Address} of the found pclntab structure, or null if not found
* @throws IOException
*/
public static Address findPclntabAddress(GoRttiContext programContext, AddressRange range,
public static Address findPclntabAddress(GoRttiMapper programContext, AddressRange range,
TaskMonitor monitor) throws IOException {
if (range == null) {
return null;
@ -141,7 +142,7 @@ public class GoPcHeader {
}
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoPcHeader> context;

View file

@ -26,7 +26,7 @@ import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.dwarf4.next.DWARFProgram;
import ghidra.app.util.bin.format.golang.*;
import ghidra.app.util.bin.format.golang.rtti.types.*;
import ghidra.app.util.bin.format.golang.structmapping.ProgramContext;
import ghidra.app.util.bin.format.golang.structmapping.DataTypeMapper;
import ghidra.app.util.bin.format.golang.structmapping.StructureMapping;
import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.opinion.ElfLoader;
@ -45,15 +45,15 @@ import ghidra.util.task.TaskMonitor;
import ghidra.util.task.UnknownProgressWrappingTaskMonitor;
/**
* {@link ProgramContext} for golang binaries.
* {@link DataTypeMapper} for golang binaries.
* <p>
* When bootstrapping golang binaries, the following steps are used:
* <ul>
* <li>Find the GoBuildInfo struct. This struct is the easiest to locate, even when the binary
* is stripped. This gives us the go pointerSize (probably same as ghidra pointer size) and the
* goVersion. This struct does not rely on StructureMapping, allowing its use before a
* ProgramContext is created.
* <li>Create ProgramContext
* DataTypeMapper is created.
* <li>Create DataTypeMapper
* <li>Find the runtime.firstmoduledata structure.
* <ul>
* <li>If there are symbols, just use the symbol or named memory block.
@ -70,18 +70,18 @@ import ghidra.util.task.UnknownProgressWrappingTaskMonitor;
* </ul>
* </ul>
*/
public class GoRttiContext extends ProgramContext {
public class GoRttiMapper extends DataTypeMapper {
/**
* Returns a new {@link GoRttiContext} for the specified program, or null if the binary
* Returns a new {@link GoRttiMapper} for the specified program, or null if the binary
* is not a supported golang binary.
*
* @param program {@link Program}
* @param log
* @return new {@link GoRttiContext}, or null if not a golang binary
* @return new {@link GoRttiMapper}, or null if not a golang binary
* @throws IOException
*/
public static GoRttiContext getContextFor(Program program, MessageLog log) throws IOException {
public static GoRttiMapper getMapperFor(Program program, MessageLog log) throws IOException {
GoBuildInfo buildInfo = GoBuildInfo.fromProgram(program);
GoVer goVer;
if (buildInfo == null || (goVer = buildInfo.getVerEnum()) == GoVer.UNKNOWN) {
@ -90,11 +90,11 @@ public class GoRttiContext extends ProgramContext {
ResourceFile gdtFile =
findGolangBootstrapGDT(goVer, buildInfo.getPointerSize(), getGolangOSString(program));
if (gdtFile == null) {
Msg.error(GoRttiContext.class, "Missing golang gdt archive for " + goVer);
Msg.error(GoRttiMapper.class, "Missing golang gdt archive for " + goVer);
}
try {
return new GoRttiContext(program, buildInfo.getPointerSize(), buildInfo.getEndian(),
return new GoRttiMapper(program, buildInfo.getPointerSize(), buildInfo.getEndian(),
buildInfo.getVerEnum(), gdtFile);
}
catch (IllegalArgumentException e) {
@ -185,7 +185,7 @@ public class GoRttiContext extends ProgramContext {
private GoType mapGoType;
private GoType chanGoType;
public GoRttiContext(Program program, int ptrSize, Endian endian, GoVer goVersion,
public GoRttiMapper(Program program, int ptrSize, Endian endian, GoVer goVersion,
ResourceFile archiveGDT) throws IOException {
super(program, archiveGDT);

View file

@ -32,7 +32,7 @@ import ghidra.util.Msg;
public class GoSlice {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoSlice> context;
@ -53,7 +53,7 @@ public class GoSlice {
this.cap = cap;
}
public GoSlice(long array, long len, long cap, GoRttiContext programContext) {
public GoSlice(long array, long len, long cap, GoRttiMapper programContext) {
this(array, len, cap);
this.programContext = programContext;
}

View file

@ -36,7 +36,7 @@ public class GoString {
private long len;
public Address getStringAddr() {
return context.getProgramContext().getDataAddress(str);
return context.getDataTypeMapper().getDataAddress(str);
}
public long getLength() {
@ -44,7 +44,7 @@ public class GoString {
}
public String getStringValue() throws IOException {
BinaryReader reader = context.getProgramContext().getReader(str);
BinaryReader reader = context.getDataTypeMapper().getReader(str);
return reader.readNextUtf8String((int) len);
}
}

View file

@ -80,7 +80,7 @@ public class GoVarlenString implements StructureReader<GoVarlenString> {
public DataType getValueDataType() {
return new ArrayDataType(CharDataType.dataType, bytes.length, -1,
context.getProgramContext().getDTM());
context.getDataTypeMapper().getDTM());
}
}

View file

@ -20,7 +20,7 @@ import java.util.Set;
import java.io.IOException;
import ghidra.app.util.bin.format.golang.rtti.GoName;
import ghidra.app.util.bin.format.golang.rtti.GoRttiContext;
import ghidra.app.util.bin.format.golang.rtti.GoRttiMapper;
import ghidra.app.util.bin.format.golang.structmapping.*;
/**
@ -43,7 +43,7 @@ public class GoBaseType {
private StructureContext<GoBaseType> context;
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@FieldMapping(signedness = Signedness.Unsigned)
private long size;

View file

@ -18,14 +18,14 @@ package ghidra.app.util.bin.format.golang.rtti.types;
import java.io.IOException;
import ghidra.app.util.bin.format.golang.rtti.GoName;
import ghidra.app.util.bin.format.golang.rtti.GoRttiContext;
import ghidra.app.util.bin.format.golang.rtti.GoRttiMapper;
import ghidra.app.util.bin.format.golang.structmapping.*;
@StructureMapping(structureName = "runtime.imethod")
public class GoIMethod implements StructureMarkup<GoIMethod> {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoIMethod> context;

View file

@ -18,14 +18,14 @@ package ghidra.app.util.bin.format.golang.rtti.types;
import java.io.IOException;
import ghidra.app.util.bin.format.golang.rtti.GoName;
import ghidra.app.util.bin.format.golang.rtti.GoRttiContext;
import ghidra.app.util.bin.format.golang.rtti.GoRttiMapper;
import ghidra.app.util.bin.format.golang.structmapping.*;
import ghidra.program.model.address.Address;
@StructureMapping(structureName = "runtime.method")
public class GoMethod implements StructureMarkup<GoMethod> {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoMethod> context;

View file

@ -35,7 +35,7 @@ import ghidra.util.Msg;
public class GoPlainType extends GoType implements StructureReader<GoType> {
@Override
public void readStructure() throws IOException {
this.typ = context.getProgramContext().readStructure(GoBaseType.class, context.getReader());
this.typ = context.getDataTypeMapper().readStructure(GoBaseType.class, context.getReader());
}
@Override

View file

@ -18,14 +18,14 @@ package ghidra.app.util.bin.format.golang.rtti.types;
import java.io.IOException;
import ghidra.app.util.bin.format.golang.rtti.GoName;
import ghidra.app.util.bin.format.golang.rtti.GoRttiContext;
import ghidra.app.util.bin.format.golang.rtti.GoRttiMapper;
import ghidra.app.util.bin.format.golang.structmapping.*;
@StructureMapping(structureName = "runtime.structfield")
public class GoStructField {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoStructField> context;
@ -45,7 +45,7 @@ public class GoStructField {
@Markup
public GoName getName() throws IOException {
return name != 0
? context.getProgramContext().readStructure(GoName.class, name)
? context.getDataTypeMapper().readStructure(GoName.class, name)
: null;
}

View file

@ -20,7 +20,7 @@ import java.util.Set;
import java.io.IOException;
import ghidra.app.util.bin.format.golang.rtti.GoRttiContext;
import ghidra.app.util.bin.format.golang.rtti.GoRttiMapper;
import ghidra.app.util.bin.format.golang.rtti.GoSlice;
import ghidra.app.util.bin.format.golang.structmapping.*;
import ghidra.program.model.data.*;
@ -38,7 +38,7 @@ public abstract class GoType implements StructureMarkup<GoType> {
Map.entry(GoKind.Map, GoMapType.class),
Map.entry(GoKind.Interface, GoInterfaceType.class));
public static Class<? extends GoType> getSpecializedTypeClass(GoRttiContext programContext,
public static Class<? extends GoType> getSpecializedTypeClass(GoRttiMapper programContext,
long offset) throws IOException {
GoTypeDetector typeDetector = programContext.readStructure(GoTypeDetector.class, offset);
Class<? extends GoType> result = specializedTypeClasses.get(typeDetector.getKind());
@ -49,7 +49,7 @@ public abstract class GoType implements StructureMarkup<GoType> {
}
@ContextField
protected GoRttiContext programContext;
protected GoRttiMapper programContext;
@ContextField
protected StructureContext<GoType> context;

View file

@ -27,7 +27,7 @@ import ghidra.util.Msg;
public class GoUncommonType {
@ContextField
private GoRttiContext programContext;
private GoRttiMapper programContext;
@ContextField
private StructureContext<GoUncommonType> context;

View file

@ -23,7 +23,7 @@ import java.lang.annotation.Target;
/**
* Indicates that the tagged field should be initialized with the value of the appropriate
* context object, either {@link ProgramContext} or {@link StructureContext}.
* context object, either {@link DataTypeMapper} or {@link StructureContext}.
*/
@Retention(RUNTIME)
@Target(FIELD)

View file

@ -38,19 +38,19 @@ import ghidra.util.task.TaskMonitor;
* Information about {@link StructureMapping} classes and their metadata, as well as
* accumulated information about structure instances that have been deserialized.
* <p>
* To use the full might and majesty of StructureMapping(tm), a ProgramContext must be created. It
* To use the full might and majesty of StructureMapping(tm), a DataTypeMapper must be created. It
* must be able to {@link #addArchiveSearchCategoryPath(CategoryPath...) find}
* ({@link #addProgramSearchCategoryPath(CategoryPath...) more find}) the Ghidra structure data
* types being used, and it must {@link #registerStructure(Class) know} about all classes that are
* going to participate during deserialization and markup.
* <p>
* Structure mapped classes can receive a reference to the specific ProgramContext type that
* created them by declaring a {@code ProgramContext} field, and tagging it with
* Structure mapped classes can receive a reference to the specific DataTypeMapper type that
* created them by declaring a {@code DataTypeMapper} field, and tagging it with
* the @{@link ContextField} annotation:
*
* <pre>
* class MyProgramContext extends ProgramContext {
* public MyProgramContext() {
* class MyDataTypeMapper extends DataTypeMapper {
* public MyDataTypeMapper() {
* ...
* registerStructure(MyDataType.class);
* }
@ -61,7 +61,7 @@ import ghidra.util.task.TaskMonitor;
* class MyDataType {
*
* &#64;ContextField
* private MyProgramContext myProgramContext;
* private MyDataTypeMapper myDataTypeMapper;
*
* &#64;ContextField
* private StructureContext&lt;MyDataType&gt; context;
@ -70,13 +70,13 @@ import ghidra.util.task.TaskMonitor;
* private long someField;
*
* void bar() {
* context.getProgramContext().getProgram(); // can only access methods defined on base ProgramContext type
* myProgramContext.foo(); // same context as previous line, but typed correctly
* context.getDataTypeMapper().getProgram(); // can only access methods defined on base DataTypeMapper type
* myDataTypeMapper.foo(); // same context as previous line, but typed correctly
* ...
* </pre>
*
*/
public class ProgramContext implements AutoCloseable {
public class DataTypeMapper implements AutoCloseable {
protected Program program;
protected DataTypeManager programDTM;
protected DataTypeManager archiveDTM;
@ -92,7 +92,7 @@ public class ProgramContext implements AutoCloseable {
* @param archiveGDT
* @throws IOException
*/
protected ProgramContext(Program program, ResourceFile archiveGDT) throws IOException {
protected DataTypeMapper(Program program, ResourceFile archiveGDT) throws IOException {
this.program = program;
this.programDTM = program.getDataTypeManager();
this.archiveDTM = archiveGDT != null
@ -126,12 +126,12 @@ public class ProgramContext implements AutoCloseable {
return DataConverter.getInstance(program.getMemory().isBigEndian());
}
public ProgramContext addProgramSearchCategoryPath(CategoryPath... paths) {
public DataTypeMapper addProgramSearchCategoryPath(CategoryPath... paths) {
programSearchCPs.addAll(Arrays.asList(paths));
return this;
}
public ProgramContext addArchiveSearchCategoryPath(CategoryPath... paths) {
public DataTypeMapper addArchiveSearchCategoryPath(CategoryPath... paths) {
archiveSearchCPs.addAll(Arrays.asList(paths));
return this;
}
@ -401,6 +401,6 @@ public class ProgramContext implements AutoCloseable {
@Override
public String toString() {
return "ProgramContext { program: %s}".formatted(program.getName());
return "DataTypeMapper { program: %s}".formatted(program.getName());
}
}

View file

@ -38,8 +38,8 @@ public record FieldContext<T> (
return structureContext.getStructureInstance();
}
public ProgramContext getProgramContext() {
return structureContext().getProgramContext();
public DataTypeMapper getDataTypeMapper() {
return structureContext().getDataTypeMapper();
}
public void appendComment(int commentType, String prefix, String comment, String sep)

View file

@ -251,7 +251,7 @@ public class FieldMappingInfo<T> {
private Object readStructureMappedTypeFunc(FieldContext<T> context) throws IOException {
return context.structureContext()
.getProgramContext()
.getDataTypeMapper()
.readStructure(field.getType(), context.reader());
}
@ -299,7 +299,7 @@ public class FieldMappingInfo<T> {
// }
private void markupNestedStructure(FieldContext<T> fieldContext) throws IOException {
fieldContext.getProgramContext().markup(fieldContext.getValue(Object.class), true);
fieldContext.getDataTypeMapper().markup(fieldContext.getValue(Object.class), true);
}
private FieldMarkupFunction<T> makeMarkupReferenceFunc(String getterName) {
@ -317,7 +317,7 @@ public class FieldMappingInfo<T> {
if (getterValue != null) {
Address addr = getterValue instanceof Address getterAddr
? getterAddr
: fieldContext.getProgramContext().getExistingStructureAddress(getterValue);
: fieldContext.getDataTypeMapper().getExistingStructureAddress(getterValue);
if (addr != null) {
fieldContext.addReference(addr);
}

View file

@ -159,7 +159,7 @@ public class FieldOutputInfo<T> {
private void dataTypeNameOutputFunc(StructureContext<T> context, Structure structure,
FieldOutputInfo<T> foi) throws IOException {
DataType dt = context.getProgramContext().getType(dataTypeName, DataType.class);
DataType dt = context.getDataTypeMapper().getType(dataTypeName, DataType.class);
if (dt == null) {
throw new IOException(
"Missing data type %s for field %s".formatted(dataTypeName, fmi.getFieldName()));
@ -175,7 +175,7 @@ public class FieldOutputInfo<T> {
private void primitiveOutputFunc(StructureContext<T> context, Structure structure,
FieldOutputInfo<T> foi) throws IOException {
DataType dt = ReflectionHelper.getPrimitiveOutputDataType(fmi.getField().getType(),
fmi.getLength(), fmi.getSignedness(), context.getProgramContext());
fmi.getLength(), fmi.getSignedness(), context.getDataTypeMapper());
preAddField(structure);
structure.add(dt, fmi.getFieldName(), null);
}
@ -185,7 +185,7 @@ public class FieldOutputInfo<T> {
// only outputs array of primitive value
Object fieldValue = foi.getValue(context.getStructureInstance(), Object.class);
DataType dt = ReflectionHelper.getArrayOutputDataType(fieldValue, fmi.getField().getType(),
fmi.getLength(), fmi.getSignedness(), context.getProgramContext());
fmi.getLength(), fmi.getSignedness(), context.getDataTypeMapper());
preAddField(structure);
structure.add(dt, fmi.getFieldName(), null);
}
@ -198,7 +198,7 @@ public class FieldOutputInfo<T> {
}
StructureContext<?> nestedStructContext =
context.getProgramContext().getExistingStructureContext(nestedStruct);
context.getDataTypeMapper().getExistingStructureContext(nestedStruct);
if (nestedStructContext == null) {
throw new IOException(
"Missing StructureContext for " + nestedStruct.getClass().getSimpleName());

View file

@ -95,24 +95,24 @@ public class ReflectionHelper {
* @param fieldType
* @param length
* @param signedness
* @param programContext
* @param dataTypeMapper
* @return
*/
public static DataType getArrayOutputDataType(Object array_value, Class<?> fieldType, int length,
Signedness signedness, ProgramContext programContext) {
Signedness signedness, DataTypeMapper dataTypeMapper) {
int arrayLen = array_value != null ? Array.getLength(array_value) : 0;
Class<?> elementType = fieldType.getComponentType();
DataType elementDT =
getPrimitiveOutputDataType(elementType, length, signedness, programContext);
getPrimitiveOutputDataType(elementType, length, signedness, dataTypeMapper);
return new ArrayDataType(elementDT, arrayLen, -1, programContext.getDTM());
return new ArrayDataType(elementDT, arrayLen, -1, dataTypeMapper.getDTM());
}
public static DataType getPrimitiveOutputDataType(Class<?> fieldType, int length,
Signedness signedness, ProgramContext programContext) {
Signedness signedness, DataTypeMapper dataTypeMapper) {
boolean isChar = (fieldType == Character.class || fieldType == Character.TYPE);
DataTypeManager dtm = programContext.getDTM();
DataTypeManager dtm = dataTypeMapper.getDTM();
if (length == -1) {
length = getPrimitiveSizeof(fieldType);
@ -125,7 +125,7 @@ public class ReflectionHelper {
if (isChar && length == 1) {
defaultDtName = "char";
}
DataType dt = programContext.getType(defaultDtName, DataType.class);
DataType dt = dataTypeMapper.getType(defaultDtName, DataType.class);
if (dt == null && isChar) {
dt = switch (length) {
case 1 -> CharDataType.dataType;

View file

@ -46,16 +46,16 @@ import ghidra.program.model.listing.Program;
* @param <T> a java class that has been tagged with a {@link StructureMapping} annotation.
*/
public class StructureContext<T> {
protected final ProgramContext programContext;
protected final DataTypeMapper dataTypeMapper;
protected final StructureMappingInfo<T> mappingInfo;
protected final BinaryReader reader;
protected final long structureStart;
protected T structureInstance;
protected Structure structureDataType;
public StructureContext(ProgramContext programContext, StructureMappingInfo<T> mappingInfo,
public StructureContext(DataTypeMapper dataTypeMapper, StructureMappingInfo<T> mappingInfo,
BinaryReader reader) {
this.programContext = programContext;
this.dataTypeMapper = dataTypeMapper;
this.mappingInfo = mappingInfo;
this.reader = reader;
this.structureStart = reader.getPointerIndex();
@ -86,19 +86,19 @@ public class StructureContext<T> {
}
/**
* Returns a reference to the root {@link ProgramContext}, as a plain ProgramContext type. If
* a more specific ProgramContext type is needed, either type-cast this value, or use
* Returns a reference to the root {@link DataTypeMapper}, as a plain DataTypeMapper type. If
* a more specific DataTypeMapper type is needed, either type-cast this value, or use
* a {@link ContextField} tag on a field in your class that specifies the correct
* ProgramContext type.
* DataTypeMapper type.
*
* @return
*/
public ProgramContext getProgramContext() {
return programContext;
public DataTypeMapper getDataTypeMapper() {
return dataTypeMapper;
}
public Program getProgram() {
return programContext.program;
return dataTypeMapper.program;
}
/**
@ -107,7 +107,7 @@ public class StructureContext<T> {
* @return {@link Address}
*/
public Address getStructureAddress() {
return programContext.getDataAddress(structureStart);
return dataTypeMapper.getDataAddress(structureStart);
}
/**
@ -198,7 +198,7 @@ public class StructureContext<T> {
*/
public void appendComment(int commentType, String prefix, String comment, String sep)
throws IOException {
DWARFUtil.appendComment(programContext.getProgram(), getStructureAddress(), commentType,
DWARFUtil.appendComment(dataTypeMapper.getProgram(), getStructureAddress(), commentType,
prefix, comment, sep);
}
@ -219,14 +219,14 @@ public class StructureContext<T> {
*/
public void markupStructure(boolean nested) throws IOException {
Address addr = getStructureAddress();
if (!nested && !programContext.markedupStructs.add(addr)) {
if (!nested && !dataTypeMapper.markedupStructs.add(addr)) {
return;
}
if (!nested) {
try {
Structure structDT = getStructureDataType();
programContext.markupAddress(addr, structDT);
dataTypeMapper.markupAddress(addr, structDT);
}
catch (IOException e) {
throw new IOException("Markup failed for structure %s at %s"
@ -237,7 +237,7 @@ public class StructureContext<T> {
if (structureInstance instanceof StructureMarkup<?> sm) {
String structureLabel = sm.getStructureLabel();
if (structureLabel != null) {
programContext.labelAddress(addr, structureLabel);
dataTypeMapper.labelAddress(addr, structureLabel);
}
}
}
@ -258,7 +258,7 @@ public class StructureContext<T> {
}
if (structureInstance instanceof StructureMarkup<?> sm) {
for (Object externalInstance : sm.getExternalInstancesToMarkup()) {
programContext.markup(externalInstance, false);
dataTypeMapper.markup(externalInstance, false);
}
}

View file

@ -34,7 +34,7 @@ import java.lang.annotation.*;
* In either case, various annotations on fields and methods will control how this structure
* will be marked up in the Ghidra program.
* <p>
* The tagged class must be {@link ProgramContext#registerStructure(Class) registered} with
* The tagged class must be {@link DataTypeMapper#registerStructure(Class) registered} with
* the program context to enable the suite of structure mapped classes to work together when
* applied to a Ghidra binary.
* <p>
@ -44,8 +44,8 @@ import java.lang.annotation.*;
* variable length fields found in the structure.
* <p>
* Structure mapped classes must have a {@link StructureContext} member variable that is tagged
* with the {@link ContextField} annotation, and probably should have a {@link ProgramContext}
* member variable (that corresponds to a more specific type of ProgramContext) that is also
* with the {@link ContextField} annotation, and probably should have a {@link DataTypeMapper}
* member variable (that corresponds to a more specific type of DataTypeMapper) that is also
* tagged with the ContextField annotation.
*
*/
@ -54,11 +54,11 @@ import java.lang.annotation.*;
public @interface StructureMapping {
/**
* Specifies the name of a Ghidra structure that the tagged class represents. For fixed
* length structures, the {@link ProgramContext} will search for this Ghidra data type
* length structures, the {@link DataTypeMapper} will search for this Ghidra data type
* in it's configured
* {@link ProgramContext#addArchiveSearchCategoryPath(ghidra.program.model.data.CategoryPath...) archive}
* {@link DataTypeMapper#addArchiveSearchCategoryPath(ghidra.program.model.data.CategoryPath...) archive}
* and
* {@link ProgramContext#addProgramSearchCategoryPath(ghidra.program.model.data.CategoryPath...) program}
* {@link DataTypeMapper#addProgramSearchCategoryPath(ghidra.program.model.data.CategoryPath...) program}
* search paths.
*
* @return

View file

@ -86,7 +86,7 @@ public class StructureMappingInfo<T> {
markupFuncs.add(context -> {
T obj = context.getStructureInstance();
Object val = ReflectionHelper.callGetter(markupGetterMethod, obj);
context.getProgramContext().markup(val, false);
context.getDataTypeMapper().markup(val, false);
});
}
@ -158,10 +158,10 @@ public class StructureMappingInfo<T> {
// used to create a structure that has variable length fields
Structure newStruct = new StructureDataType(
context.getProgramContext().getDefaultVariableLengthStructCategoryPath(),
context.getDataTypeMapper().getDefaultVariableLengthStructCategoryPath(),
structureName,
0,
context.getProgramContext().getDTM());
context.getDataTypeMapper().getDTM());
// TODO: set struct packing?
@ -200,14 +200,14 @@ public class StructureMappingInfo<T> {
* @throws IOException
*/
public void assignContextFieldValues(StructureContext<T> context) throws IOException {
Class<?> programContextType = context.getProgramContext().getClass();
Class<?> dataTypeMapperType = context.getDataTypeMapper().getClass();
Class<?> structureContextType = context.getClass();
T obj = context.getStructureInstance();
for (Field f : contextFields) {
Class<?> fieldType = f.getType();
if (fieldType.isAssignableFrom(programContextType)) {
ReflectionHelper.assignField(f, obj, context.getProgramContext());
if (fieldType.isAssignableFrom(dataTypeMapperType)) {
ReflectionHelper.assignField(f, obj, context.getDataTypeMapper());
}
else if (fieldType.isAssignableFrom(structureContextType)) {
ReflectionHelper.assignField(f, obj, context);