From 514fc2fc54aa2eb31502e371593230c9598da67a Mon Sep 17 00:00:00 2001 From: Andrew Strelsky Date: Sun, 31 Dec 2023 09:58:16 -0500 Subject: [PATCH 1/2] golang support 1.21+ --- .../ghidra/app/util/bin/format/golang/GoVer.java | 4 +++- .../format/golang/rtti/types/GoArrayType.java | 2 +- .../bin/format/golang/rtti/types/GoBaseType.java | 8 ++++---- .../bin/format/golang/rtti/types/GoChanType.java | 2 +- .../bin/format/golang/rtti/types/GoFuncType.java | 2 +- .../bin/format/golang/rtti/types/GoIMethod.java | 4 ++-- .../golang/rtti/types/GoInterfaceType.java | 4 ++-- .../bin/format/golang/rtti/types/GoMapType.java | 4 ++-- .../bin/format/golang/rtti/types/GoMethod.java | 2 +- .../format/golang/rtti/types/GoPlainType.java | 2 +- .../format/golang/rtti/types/GoPointerType.java | 2 +- .../format/golang/rtti/types/GoSliceType.java | 2 +- .../format/golang/rtti/types/GoStructField.java | 2 +- .../format/golang/rtti/types/GoStructType.java | 2 +- .../bin/format/golang/rtti/types/GoType.java | 2 +- .../format/golang/rtti/types/GoTypeDetector.java | 4 ++-- .../format/golang/rtti/types/GoUncommonType.java | 2 +- .../golang/structmapping/DataTypeMapper.java | 11 ++++++++--- .../golang/structmapping/StructureMapping.java | 2 +- .../structmapping/StructureMappingInfo.java | 16 ++++++++-------- 20 files changed, 43 insertions(+), 36 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoVer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoVer.java index 06608003fb..1afa8e4294 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoVer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoVer.java @@ -28,7 +28,9 @@ public enum GoVer { V1_17(1, 17), V1_18(1, 18), V1_19(1, 19), - V1_20(1, 20); + V1_20(1, 20), + V1_21(1, 21), + V1_22(1, 22); private final int major; private final int minor; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoArrayType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoArrayType.java index d2f1a305fb..1719ffceb9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoArrayType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoArrayType.java @@ -26,7 +26,7 @@ import ghidra.program.model.data.DataType; /** * {@link GoType} structure that defines an array. */ -@StructureMapping(structureName = "runtime.arraytype") +@StructureMapping(structureName = {"runtime.arraytype", "internal/abi.ArrayType"}) public class GoArrayType extends GoType { @FieldMapping diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoBaseType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoBaseType.java index 18b3ab4238..a0d68d17b4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoBaseType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoBaseType.java @@ -35,7 +35,7 @@ import ghidra.app.util.bin.format.golang.structmapping.*; * struct specialized_type { basetype_struct; (various_fields)* } struct uncommon; * */ -@StructureMapping(structureName = "runtime._type") +@StructureMapping(structureName = {"runtime._type", "internal/abi.Type"}) public class GoBaseType { @ContextField @@ -44,17 +44,17 @@ public class GoBaseType { @ContextField private GoRttiMapper programContext; - @FieldMapping(signedness = Signedness.Unsigned) + @FieldMapping(fieldName = {"size", "Size_"}, signedness = Signedness.Unsigned) private long size; - @FieldMapping + @FieldMapping(fieldName = {"ptrdata", "PtrBytes"}) private long ptrdata; @FieldMapping @EOLComment("flags") private int tflag; - @FieldMapping + @FieldMapping(fieldName = {"kind", "Kind_"}) @EOLComment private int kind; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoChanType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoChanType.java index f30fb2173a..5fbd13addb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoChanType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoChanType.java @@ -25,7 +25,7 @@ import ghidra.util.Msg; /** * A {@link GoType} structure that defines a go channel */ -@StructureMapping(structureName = "runtime.chantype") +@StructureMapping(structureName = {"runtime.chantype", "internal/abi.ChanType"}) public class GoChanType extends GoType { @FieldMapping diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoFuncType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoFuncType.java index 87da2072cf..af85ddff3f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoFuncType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoFuncType.java @@ -27,7 +27,7 @@ import ghidra.program.model.data.*; /** * A {@link GoType} structure that defines a function type. */ -@StructureMapping(structureName = "runtime.functype") +@StructureMapping(structureName = {"runtime.functype", "internal/abi.FuncType"}) public class GoFuncType extends GoType { /** diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoIMethod.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoIMethod.java index 8f6b2f1b77..8b0f7eaa0c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoIMethod.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoIMethod.java @@ -22,7 +22,7 @@ import ghidra.app.util.bin.format.golang.structmapping.*; import ghidra.program.model.address.Address; import ghidra.program.model.data.FunctionDefinition; -@StructureMapping(structureName = "runtime.imethod") +@StructureMapping(structureName = {"runtime.imethod", "internal/abi.Imethod"}) public class GoIMethod implements StructureMarkup { @ContextField @@ -36,7 +36,7 @@ public class GoIMethod implements StructureMarkup { @EOLComment("getName") private long name; - @FieldMapping + @FieldMapping(fieldName = {"ityp", "Typ"}) @MarkupReference("getType") private long ityp; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoInterfaceType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoInterfaceType.java index 26aa5fc2be..8382a02844 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoInterfaceType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoInterfaceType.java @@ -28,14 +28,14 @@ import ghidra.util.exception.CancelledException; /** * A {@link GoType} structure that defines a golang interface. */ -@StructureMapping(structureName = "runtime.interfacetype") +@StructureMapping(structureName = {"runtime.interfacetype", "internal/abi.InterfaceType"}) public class GoInterfaceType extends GoType { @FieldMapping @MarkupReference("getPkgPath") private long pkgpath; // pointer to name - @FieldMapping + @FieldMapping(fieldName = {"mhdr", "Methods"}) private GoSlice mhdr; public GoInterfaceType() { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoMapType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoMapType.java index 290f21b257..85be7d9247 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoMapType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoMapType.java @@ -30,7 +30,7 @@ import ghidra.util.Msg; * See {@link GoRttiMapper#getMapGoType()} or the "runtime.hmap" type for the definition of * a instance of a map variable in memory. */ -@StructureMapping(structureName = "runtime.maptype") +@StructureMapping(structureName = {"runtime.maptype", "internal/abi.MapType"}) public class GoMapType extends GoType { @FieldMapping @@ -51,7 +51,7 @@ public class GoMapType extends GoType { @FieldMapping private int keysize; - @FieldMapping + @FieldMapping(fieldName = {"elemsize", "ValueSize"}) private int elemsize; @FieldMapping diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoMethod.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoMethod.java index b67e235e48..7dc3c57518 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoMethod.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoMethod.java @@ -28,7 +28,7 @@ import ghidra.util.NumericUtilities; /** * Structure that defines a method for a GoType, found in the type's {@link GoUncommonType} struct. */ -@StructureMapping(structureName = "runtime.method") +@StructureMapping(structureName = {"runtime.method", "internal/abi.Method"}) public class GoMethod implements StructureMarkup { @ContextField private GoRttiMapper programContext; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPlainType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPlainType.java index 2b1de93894..4647a8307a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPlainType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPlainType.java @@ -32,7 +32,7 @@ import ghidra.util.Msg; *

* {@link GoType} structure that defines a built-in primitive type. */ -@StructureMapping(structureName = "runtime._type") +@StructureMapping(structureName = {"runtime._type", "internal/abi.Type"}) public class GoPlainType extends GoType implements StructureReader { @Override public void readStructure() throws IOException { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPointerType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPointerType.java index d6aaa1daf8..6d4824a31b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPointerType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPointerType.java @@ -26,7 +26,7 @@ import ghidra.program.model.data.PointerDataType; /** * {@link GoType} structure that defines a pointer. */ -@StructureMapping(structureName = "runtime.ptrtype") +@StructureMapping(structureName = {"runtime.ptrtype", "internal/abi.PtrType"}) public class GoPointerType extends GoType { @FieldMapping @MarkupReference("getElement") diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoSliceType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoSliceType.java index e97b1dd8aa..d63242df45 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoSliceType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoSliceType.java @@ -29,7 +29,7 @@ import ghidra.program.model.data.*; * See {@link GoRttiMapper#getGenericSliceDT()} or the "runtime.slice" type for the definition of * a instance of a slice variable in memory. */ -@StructureMapping(structureName = "runtime.slicetype") +@StructureMapping(structureName = {"runtime.slicetype", "internal/abi.SliceType"}) public class GoSliceType extends GoType { @FieldMapping diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoStructField.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoStructField.java index 843a117cca..1474c29559 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoStructField.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoStructField.java @@ -24,7 +24,7 @@ import ghidra.app.util.bin.format.golang.structmapping.*; /** * Structure used to define a field in a {@link GoStructType struct type}. */ -@StructureMapping(structureName = "runtime.structfield") +@StructureMapping(structureName = {"runtime.structfield", "internal/abi.StructField"}) public class GoStructField { @ContextField diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoStructType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoStructType.java index 4a4cab90a3..85f7de8b62 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoStructType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoStructType.java @@ -29,7 +29,7 @@ import ghidra.util.exception.CancelledException; /** * Golang type information about a specific structure type. */ -@StructureMapping(structureName = "runtime.structtype") +@StructureMapping(structureName = {"runtime.structtype", "internal/abi.StructType"}) public class GoStructType extends GoType { @FieldMapping diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoType.java index ea61eff210..e7836716cc 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoType.java @@ -69,7 +69,7 @@ public abstract class GoType implements StructureMarkup { @ContextField protected StructureContext context; - @FieldMapping + @FieldMapping(fieldName = {"typ", "Type"}) @Markup @FieldOutput protected GoBaseType typ; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoTypeDetector.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoTypeDetector.java index 2d9ef56caa..6ebcf3b957 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoTypeDetector.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoTypeDetector.java @@ -21,9 +21,9 @@ import ghidra.app.util.bin.format.golang.structmapping.StructureMapping; /** * Small stub that is only used to fetch the "kind" field so that the real gotype can be detected */ -@StructureMapping(structureName = "runtime._type") +@StructureMapping(structureName = {"runtime._type", "internal/abi.Type"}) public class GoTypeDetector { - @FieldMapping + @FieldMapping(fieldName = {"kind", "Kind_"}) private int kind; public GoKind getKind() { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoUncommonType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoUncommonType.java index 35eef0ed35..7b216afb23 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoUncommonType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoUncommonType.java @@ -26,7 +26,7 @@ import ghidra.util.Msg; * Structure found immediately after a {@link GoType} structure, if it has the uncommon flag * set. */ -@StructureMapping(structureName = "runtime.uncommontype") +@StructureMapping(structureName = {"runtime.uncommontype", "internal/abi.UncommonType"}) public class GoUncommonType { @ContextField diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/DataTypeMapper.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/DataTypeMapper.java index 8291943656..ce37b9cffd 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/DataTypeMapper.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/DataTypeMapper.java @@ -170,11 +170,16 @@ public class DataTypeMapper implements AutoCloseable { */ public void registerStructure(Class clazz) throws IOException { Structure structDT = null; - String structName = StructureMappingInfo.getStructureDataTypeNameForClass(clazz); - if (structName != null && !structName.isBlank()) { - structDT = getType(structName, Structure.class); + for (String structName : StructureMappingInfo.getStructureDataTypeNameForClass(clazz)) { + if (structName != null && !structName.isBlank()) { + structDT = getType(structName, Structure.class); + if (structDT != null) { + break; + } + } } if (!StructureReader.class.isAssignableFrom(clazz) && structDT == null) { + String structName = StructureMappingInfo.getStructureDataTypeNameForClass(clazz)[0]; if (structName == null || structName.isBlank()) { structName = ""; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMapping.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMapping.java index cf0bd953ce..9a57869518 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMapping.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMapping.java @@ -63,7 +63,7 @@ public @interface StructureMapping { * * @return name of a Ghidra structure data type */ - String structureName(); + String[] structureName(); /** * Optional reference to a 'function' (implemented via a class) that will be called to do diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMappingInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMappingInfo.java index 8184b4d14b..0ed897cdeb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMappingInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMappingInfo.java @@ -39,7 +39,7 @@ public class StructureMappingInfo { * @param targetClass structure mapped class * @return the structure name */ - public static String getStructureDataTypeNameForClass(Class targetClass) { + public static String[] getStructureDataTypeNameForClass(Class targetClass) { StructureMapping sma = targetClass.getAnnotation(StructureMapping.class); return sma != null ? sma.structureName() : null; } @@ -68,7 +68,7 @@ public class StructureMappingInfo { private final Class targetClass; private final ObjectInstanceCreator instanceCreator; - private final String structureName; + private final String[] structureName; private final Structure structureDataType; // null if variable length fields private final List> fields = new ArrayList<>(); @@ -84,7 +84,7 @@ public class StructureMappingInfo { this.targetClass = targetClass; this.structureDataType = structDataType; this.structureName = structureDataType != null - ? structureDataType.getName() + ? new String[]{structureDataType.getName()} : sma.structureName(); this.useFieldMappingInfo = !StructureReader.class.isAssignableFrom(targetClass); this.instanceCreator = findInstanceCreator(); @@ -109,7 +109,7 @@ public class StructureMappingInfo { } public String getDescription() { - return "%s-%s".formatted(targetClass.getSimpleName(), structureName); + return "%s-%s".formatted(targetClass.getSimpleName(), structureName[0]); } public Structure getStructureDataType() { @@ -117,7 +117,7 @@ public class StructureMappingInfo { } public String getStructureName() { - return structureName; + return structureName[0]; } public int getStructureLength() { @@ -187,7 +187,7 @@ public class StructureMappingInfo { Structure newStruct = new StructureDataType( context.getDataTypeMapper().getDefaultVariableLengthStructCategoryPath(), - structureName, + structureName[0], 0, context.getDataTypeMapper().getDTM()); @@ -204,7 +204,7 @@ public class StructureMappingInfo { } if (!nameSuffix.isEmpty()) { try { - newStruct.setName(structureName + nameSuffix); + newStruct.setName(structureName[0] + nameSuffix); } catch (InvalidNameException | DuplicateNameException e) { throw new IOException(e); @@ -264,7 +264,7 @@ public class StructureMappingInfo { return null; } for (DataTypeComponent dtc : structureDataType.getDefinedComponents()) { - if (name.equals(dtc.getFieldName())) { + if (name.equalsIgnoreCase(dtc.getFieldName())) { return dtc; } } From 5e18efdd0d3a00d6836b49b7972ad9e91f5a7e1d Mon Sep 17 00:00:00 2001 From: dev747368 <48332326+dev747368@users.noreply.github.com> Date: Thu, 4 Jan 2024 19:26:52 +0000 Subject: [PATCH 2/2] GP-4183 add golang 1.21 support --- Ghidra/Features/Base/certification.manifest | 1 + .../golang/golang_1.21_anybit_any.gdt | Bin 0 -> 11977 bytes .../core/analysis/GolangStringAnalyzer.java | 2 +- .../core/analysis/GolangSymbolAnalyzer.java | 3 +- .../format/golang/BootstrapInfoException.java | 38 ++++++++ .../app/util/bin/format/golang/GoVer.java | 4 +- .../bin/format/golang/rtti/GoRttiMapper.java | 81 ++++++++++-------- .../golang/structmapping/DataTypeMapper.java | 63 ++++++++++---- .../golang/structmapping/FieldMapping.java | 10 +-- .../structmapping/StructureMapping.java | 32 +++---- .../structmapping/StructureMappingInfo.java | 61 ++++++------- .../core/datamgr/DataTypeArchiveIDTest.java | 23 ++--- .../languages/x86-64-golang.register.info | 2 +- 13 files changed, 197 insertions(+), 123 deletions(-) create mode 100644 Ghidra/Features/Base/data/typeinfo/golang/golang_1.21_anybit_any.gdt create mode 100644 Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/BootstrapInfoException.java diff --git a/Ghidra/Features/Base/certification.manifest b/Ghidra/Features/Base/certification.manifest index 64a1f11ba3..e4381a5bcf 100644 --- a/Ghidra/Features/Base/certification.manifest +++ b/Ghidra/Features/Base/certification.manifest @@ -91,6 +91,7 @@ data/typeinfo/golang/golang_1.17_anybit_any.gdt||GHIDRA||||END| data/typeinfo/golang/golang_1.18_anybit_any.gdt||GHIDRA||||END| data/typeinfo/golang/golang_1.19_anybit_any.gdt||GHIDRA||||END| data/typeinfo/golang/golang_1.20_anybit_any.gdt||GHIDRA||||END| +data/typeinfo/golang/golang_1.21_anybit_any.gdt||GHIDRA||||END| data/typeinfo/golang/runtimesnapshot.go||GHIDRA||||END| data/typeinfo/mac_10.9/mac_osx.gdt||GHIDRA||||END| data/typeinfo/rust/rust-common.gdt||GHIDRA||||END| diff --git a/Ghidra/Features/Base/data/typeinfo/golang/golang_1.21_anybit_any.gdt b/Ghidra/Features/Base/data/typeinfo/golang/golang_1.21_anybit_any.gdt new file mode 100644 index 0000000000000000000000000000000000000000..55ae6c9ca6ea9f1294a32e229e44dae51c202b60 GIT binary patch literal 11977 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 R+qGXjzN#$5oflpAe*hhegM0u0 literal 0 HcmV?d00001 diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangStringAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangStringAnalyzer.java index c36732635c..31800b3d7c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangStringAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangStringAnalyzer.java @@ -99,7 +99,7 @@ public class GolangStringAnalyzer extends AbstractAnalyzer { goBinary = GoRttiMapper.getSharedGoBinary(program, monitor); if (goBinary == null) { - Msg.error(this, "Golang analyzer error: unable to get GoRttiMapper"); + Msg.error(this, "Golang string analyzer error: unable to get GoRttiMapper"); return false; } markupSession = goBinary.createMarkupSession(monitor); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java index bfa1580741..03aa973861 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java @@ -112,7 +112,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer { goBinary = GoRttiMapper.getSharedGoBinary(program, monitor); if (goBinary == null) { - Msg.error(this, "Golang analyzer error: unable to get GoRttiMapper"); + Msg.error(this, "Golang symbol analyzer error: unable to get GoRttiMapper"); return false; } @@ -136,6 +136,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer { } if (analyzerOptions.propagateRtti) { + Msg.info(this, "Golang symbol analyzer: scheduling RTTI propagation after reference analysis"); aam.schedule(new PropagateRttiBackgroundCommand(goBinary), AnalysisPriority.REFERENCE_ANALYSIS.after().priority()); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/BootstrapInfoException.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/BootstrapInfoException.java new file mode 100644 index 0000000000..b68f8fd72f --- /dev/null +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/BootstrapInfoException.java @@ -0,0 +1,38 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.golang; + +import java.io.IOException; + +public class BootstrapInfoException extends IOException { + + public BootstrapInfoException() { + // empty + } + + public BootstrapInfoException(String message) { + super(message); + } + + public BootstrapInfoException(Throwable cause) { + super(cause); + } + + public BootstrapInfoException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoVer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoVer.java index 1afa8e4294..b9f6bca38f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoVer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoVer.java @@ -35,7 +35,7 @@ public enum GoVer { private final int major; private final int minor; - private GoVer(int major, int minor) { + GoVer(int major, int minor) { this.major = major; this.minor = minor; } @@ -91,7 +91,7 @@ public enum GoVer { } } catch (NumberFormatException e) { - return UNKNOWN; + // fall thru, return unknown } return UNKNOWN; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java index c835584f31..f5e194dc4b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java @@ -112,54 +112,63 @@ public class GoRttiMapper extends DataTypeMapper { GoRttiMapper supplier_result = getGoBinary(program); if (supplier_result != null) { supplier_result.init(monitor); + return supplier_result; } - return supplier_result; } - catch (IllegalArgumentException | IOException e) { - TransientProgramProperties.getProperty(program, FAILED_FLAG, - TransientProgramProperties.SCOPE.PROGRAM, Boolean.class, () -> true); // also sets it - - if (e instanceof IOException) { - // this is a more serious error, and the stack trace should be written - // to the application log - Msg.error(GoRttiMapper.class, - "Failed to read golang info for: " + program.getName(), e); - - } - AutoAnalysisManager aam = AutoAnalysisManager.getAnalysisManager(program); - if (aam.isAnalyzing()) { - // should cause a modal popup at end of analysis that the go binary wasn't - // supported - MessageLog log = aam.getMessageLog(); - log.appendMsg(e.getMessage()); - } - else { - Msg.warn(GoRttiMapper.class, "Golang program: " + e.getMessage()); - } - - return null; + catch (BootstrapInfoException mbie) { + Msg.warn(GoRttiMapper.class, mbie.getMessage()); + logAnalyzerMsg(program, mbie.getMessage()); } + catch (IOException e) { + // this is a more serious error, and the stack trace should be written + // to the application log + Msg.error(GoRttiMapper.class, "Failed to read golang info", e); + logAnalyzerMsg(program, e.getMessage()); + } + + // this sets the failed flag + TransientProgramProperties.getProperty(program, FAILED_FLAG, + TransientProgramProperties.SCOPE.PROGRAM, Boolean.class, () -> true); + + return null; }); return goBinary; } + private static void logAnalyzerMsg(Program program, String msg) { + AutoAnalysisManager aam = AutoAnalysisManager.getAnalysisManager(program); + if (aam.isAnalyzing()) { + // should cause a modal popup at end of analysis that will show the message + MessageLog log = aam.getMessageLog(); + log.appendMsg(msg); + } + } + /** * Creates a {@link GoRttiMapper} representing the specified program. * * @param program {@link Program} * @return new {@link GoRttiMapper}, or null if basic golang information is not found in the * binary - * @throws IllegalArgumentException if the golang binary is an unsupported version + * @throws BootstrapInfoException if it is a golang binary and has an unsupported or + * unparseable version number or if there was a missing golang bootstrap .gdt file * @throws IOException if there was an error in the Ghidra golang rtti reading logic */ public static GoRttiMapper getGoBinary(Program program) - throws IllegalArgumentException, IOException { + throws BootstrapInfoException, IOException { GoBuildInfo buildInfo = GoBuildInfo.fromProgram(program); - GoVer goVer; - if (buildInfo == null || (goVer = buildInfo.getVerEnum()) == GoVer.UNKNOWN) { + if (buildInfo == null) { + // probably not a golang binary return null; } + + GoVer goVer = buildInfo.getVerEnum(); + if (goVer == GoVer.UNKNOWN) { + throw new BootstrapInfoException( + "Unsupported Golang version, version info: '%s'".formatted(buildInfo.getVersion())); + } + ResourceFile gdtFile = findGolangBootstrapGDT(goVer, buildInfo.getPointerSize(), getGolangOSString(program)); if (gdtFile == null) { @@ -324,11 +333,11 @@ public class GoRttiMapper extends DataTypeMapper { * if not present and types recovered via DWARF should be used instead * @throws IOException if error linking a structure mapped structure to its matching * ghidra structure, which is a programming error or a corrupted bootstrap gdt - * @throws IllegalArgumentException if there is no matching bootstrap gdt for this specific + * @throws BootstrapInfoException if there is no matching bootstrap gdt for this specific * type of golang binary */ public GoRttiMapper(Program program, int ptrSize, Endian endian, GoVer goVersion, - ResourceFile archiveGDT) throws IOException, IllegalArgumentException { + ResourceFile archiveGDT) throws IOException, BootstrapInfoException { super(program, archiveGDT); this.goVersion = goVersion; @@ -357,13 +366,15 @@ public class GoRttiMapper extends DataTypeMapper { if (archiveGDT == null) { // a normal'ish situation where there isn't a .gdt for this arch/binary and there // isn't any DWARF. - throw new IllegalArgumentException( - "Missing golang .gdt archive for %s, no fallback DWARF info, unable to extract golang RTTI info." + throw new BootstrapInfoException( + "Missing golang .gdt archive for %s, no fallback DWARF info, unable to extract Golang RTTI info." .formatted(goVersion)); } - // a bad situation where the data type info is corrupted - throw new IOException("Invalid or missing Golang bootstrap GDT file: %s" - .formatted(archiveGDT.getAbsolutePath())); + + // we have a .gdt, but something failed. + throw new IOException("Invalid Golang bootstrap GDT file or struct mapping info: %s" + .formatted(archiveGDT.getAbsolutePath()), + e); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/DataTypeMapper.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/DataTypeMapper.java index ce37b9cffd..246e3da45d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/DataTypeMapper.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/DataTypeMapper.java @@ -169,26 +169,30 @@ public class DataTypeMapper implements AutoCloseable { * @throws IOException if the class's Ghidra structure data type could not be found */ public void registerStructure(Class clazz) throws IOException { - Structure structDT = null; - for (String structName : StructureMappingInfo.getStructureDataTypeNameForClass(clazz)) { - if (structName != null && !structName.isBlank()) { - structDT = getType(structName, Structure.class); - if (structDT != null) { - break; - } + StructureMapping sma = clazz.getAnnotation(StructureMapping.class); + List structNames = sma != null ? Arrays.asList(sma.structureName()) : List.of(); + Structure structDT = getType(structNames, Structure.class); + if (structDT == null) { + String dtName = structNames.isEmpty() ? "" : String.join("|", structNames); + if (!StructureReader.class.isAssignableFrom(clazz)) { + throw new IOException("Missing struct definition for class %s, structure name: [%s]" + .formatted(clazz.getSimpleName(), dtName)); } - } - if (!StructureReader.class.isAssignableFrom(clazz) && structDT == null) { - String structName = StructureMappingInfo.getStructureDataTypeNameForClass(clazz)[0]; - if (structName == null || structName.isBlank()) { - structName = ""; + if (structNames.size() != 1) { + throw new IOException( + "Bad StructMapping,StructureReader definition for class %s, structure name: [%s]" + .formatted(clazz.getSimpleName(), dtName)); } - throw new IOException( - "Missing struct definition %s - %s".formatted(clazz.getSimpleName(), structName)); } - StructureMappingInfo structMappingInfo = StructureMappingInfo.fromClass(clazz, structDT); - mappingInfo.put(clazz, structMappingInfo); + try { + StructureMappingInfo structMappingInfo = + StructureMappingInfo.fromClass(clazz, structDT); + mappingInfo.put(clazz, structMappingInfo); + } + catch (IllegalArgumentException e) { + throw new IOException(e.getMessage()); + } } /** @@ -287,7 +291,32 @@ public class DataTypeMapper implements AutoCloseable { } /** - * Returns a named {@link DataType}, searching the registered + * Returns a named {@link DataType}, searching the registered + * {@link #addProgramSearchCategoryPath(CategoryPath...) program} + * and {@link #addArchiveSearchCategoryPath(CategoryPath...) archive} category paths. + *

+ * DataTypes that were found in the attached archive gdt manager will be copied into the + * program's data type manager before being returned. + * + * @param DataType or derived type + * @param names list containing the data type name and any alternates + * @param clazz expected DataType class + * @return DataType or null if not found + */ + public T getType(List names, Class clazz) { + for (String dtName : names) { + if (dtName != null && !dtName.isBlank()) { + T result = getType(dtName, clazz); + if (result != null) { + return result; + } + } + } + return null; + } + + /** + * Returns a named {@link DataType}, searching the registered * {@link #addProgramSearchCategoryPath(CategoryPath...) program} * and {@link #addArchiveSearchCategoryPath(CategoryPath...) archive} category paths. *

diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/FieldMapping.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/FieldMapping.java index c0545d61b4..29ccc9f54f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/FieldMapping.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/FieldMapping.java @@ -15,8 +15,8 @@ */ package ghidra.app.util.bin.format.golang.structmapping; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -44,10 +44,10 @@ public @interface FieldMapping { * Overrides the field name that is matched in the structure. *

* Can be a single name, or a list of names that will be used to find the structure - * field. + * field. The name is case-insensitive. * - * @return name, or list of names, of the structure field to map, or unset to use the - * java field's name + * @return name, or list of names (case insensitive), of the structure field to map, + * or unset to use the java field's name */ String[] fieldName() default ""; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMapping.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMapping.java index 9a57869518..6e8fa375a1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMapping.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMapping.java @@ -21,54 +21,54 @@ import java.lang.annotation.*; * Indicates that the tagged class corresponds to a Ghidra structure. *

* For fixed/static length structures, an existing Ghidra structure data type will be found and - * then bound to the tagged class, and it will control how instances of the tagged class + * then bound to the tagged class, and it will control how instances of the tagged class * are deserialized. Only fields that are interesting / relevant need to be tagged with - * a {@link FieldMapping} annotation, which causes them to be pulled into the java structure. + * a {@link FieldMapping} annotation, which causes them to be pulled into the java class. *

- * For {@link FieldOutput#isVariableLength() variable} length structures, a unique Ghidra + * For {@link FieldOutput#isVariableLength() variable} length structures, a unique Ghidra * structure data type will be created for each combination of field lengths, and the tagged * class must deserialize itself by implementing the {@link StructureReader} interface. (each * field that needs to be mapped into the Ghidra structure must be tagged with a {@link FieldOutput} * annotation) *

- * In either case, various annotations on fields and methods will control how this structure + * In either case, various annotations on fields and methods will control how this structure * will be marked up in the Ghidra program. *

* The tagged class must be {@link DataTypeMapper#registerStructure(Class) registered} with - * the {@link DataTypeMapper program context} to enable the suite of structure mapped classes + * the {@link DataTypeMapper program context} to enable the suite of structure mapped classes * to work together when applied to a Ghidra binary. *

* For variable length structure classes, when the struct mapping system creates a custom-fitted * structure to markup a specific location with its specific data, the new struct data type's name * will be patterned as "structurename_NN_MM_...", where NN and MM and etc are the lengths of the - * variable length fields found in the structure. + * variable length fields found in the structure. *

* Structure mapped classes must have a {@link StructureContext} member variable that is tagged * 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 + * member variable (that corresponds to a more specific type of DataTypeMapper) that is also * tagged with the ContextField annotation. - * + * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface StructureMapping { /** - * Specifies the name of a Ghidra structure that the tagged class represents. For fixed - * length structures, the {@link DataTypeMapper} will search for this Ghidra data type - * in it's configured + * Specifies the name, and optionally alternate names, of a Ghidra structure that the tagged + * class represents. For fixed length structures, the {@link DataTypeMapper} will search + * for this Ghidra data type in it's configured * {@link DataTypeMapper#addArchiveSearchCategoryPath(ghidra.program.model.data.CategoryPath...) archive} - * and + * and * {@link DataTypeMapper#addProgramSearchCategoryPath(ghidra.program.model.data.CategoryPath...) program} * search paths. - * - * @return name of a Ghidra structure data type + * + * @return name(s) of a Ghidra structure data type */ String[] structureName(); /** - * Optional reference to a 'function' (implemented via a class) that will be called to do + * Optional reference to a 'function' (implemented via a class) that will be called to do * custom markup. - * + * * @return {@link StructureMarkupFunction} class */ @SuppressWarnings("rawtypes") diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMappingInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMappingInfo.java index 0ed897cdeb..10927ebdd9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMappingInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/structmapping/StructureMappingInfo.java @@ -32,18 +32,6 @@ import ghidra.util.exception.DuplicateNameException; */ public class StructureMappingInfo { - /** - * Returns the name of the structure data type that will define the binary layout - * of the mapped fields in the target class. - * - * @param targetClass structure mapped class - * @return the structure name - */ - public static String[] getStructureDataTypeNameForClass(Class targetClass) { - StructureMapping sma = targetClass.getAnnotation(StructureMapping.class); - return sma != null ? sma.structureName() : null; - } - /** * Returns the mapping info for a class, using annotations found in that class. * @@ -68,8 +56,9 @@ public class StructureMappingInfo { private final Class targetClass; private final ObjectInstanceCreator instanceCreator; - private final String[] structureName; + private final String structureName; private final Structure structureDataType; // null if variable length fields + private final Map fieldNameLookup; // case insensitive lookup private final List> fields = new ArrayList<>(); private final List> outputFields = new ArrayList<>(); @@ -84,8 +73,9 @@ public class StructureMappingInfo { this.targetClass = targetClass; this.structureDataType = structDataType; this.structureName = structureDataType != null - ? new String[]{structureDataType.getName()} - : sma.structureName(); + ? structureDataType.getName() + : sma.structureName()[0]; + this.fieldNameLookup = indexStructFields(structDataType); this.useFieldMappingInfo = !StructureReader.class.isAssignableFrom(targetClass); this.instanceCreator = findInstanceCreator(); @@ -109,7 +99,7 @@ public class StructureMappingInfo { } public String getDescription() { - return "%s-%s".formatted(targetClass.getSimpleName(), structureName[0]); + return "%s-%s".formatted(targetClass.getSimpleName(), structureName); } public Structure getStructureDataType() { @@ -117,7 +107,7 @@ public class StructureMappingInfo { } public String getStructureName() { - return structureName[0]; + return structureName; } public int getStructureLength() { @@ -187,7 +177,7 @@ public class StructureMappingInfo { Structure newStruct = new StructureDataType( context.getDataTypeMapper().getDefaultVariableLengthStructCategoryPath(), - structureName[0], + structureName, 0, context.getDataTypeMapper().getDTM()); @@ -204,7 +194,7 @@ public class StructureMappingInfo { } if (!nameSuffix.isEmpty()) { try { - newStruct.setName(structureName[0] + nameSuffix); + newStruct.setName(structureName + nameSuffix); } catch (InvalidNameException | DuplicateNameException e) { throw new IOException(e); @@ -259,18 +249,6 @@ public class StructureMappingInfo { } } - private DataTypeComponent getField(String name) { - if (!useFieldMappingInfo || name == null || name.isBlank()) { - return null; - } - for (DataTypeComponent dtc : structureDataType.getDefinedComponents()) { - if (name.equalsIgnoreCase(dtc.getFieldName())) { - return dtc; - } - } - return null; - } - private void readFieldInfo(Class clazz) { Class superclass = clazz.getSuperclass(); if (superclass != null) { @@ -316,8 +294,9 @@ public class StructureMappingInfo { if (fma.optional()) { return null; } - throw new IllegalArgumentException("Missing structure field: %s in %s" - .formatted(Arrays.toString(fieldNames), targetClass.getSimpleName())); + throw new IllegalArgumentException( + "Missing structure field: %s.%s for %s.%s".formatted(structureName, + Arrays.toString(fieldNames), targetClass.getSimpleName(), field.getName())); } Signedness signedness = fma != null ? fma.signedness() : Signedness.Unspecified; @@ -346,7 +325,7 @@ public class StructureMappingInfo { private DataTypeComponent getFirstMatchingField(String[] fieldNames) { for (String fieldName : fieldNames) { - DataTypeComponent dtc = getField(fieldName); + DataTypeComponent dtc = fieldNameLookup.get(fieldName.toLowerCase()); if (dtc != null) { return dtc; } @@ -400,6 +379,20 @@ public class StructureMappingInfo { return struct.isZeroLength() ? 0 : struct.getLength(); } + private static Map indexStructFields(Structure struct) { + if (struct == null) { + return Map.of(); + } + Map result = new HashMap<>(); + for (DataTypeComponent dtc : struct.getDefinedComponents()) { + String fieldName = dtc.getFieldName(); + if (fieldName != null) { + result.put(fieldName.toLowerCase(), dtc); + } + } + return result; + } + //--------------------------------------------------------------------------------------------- interface ReadFromStructureFunction { T readStructure(StructureContext context) throws IOException; diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/DataTypeArchiveIDTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/DataTypeArchiveIDTest.java index 827bc672cc..d9dda4b7ae 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/DataTypeArchiveIDTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/DataTypeArchiveIDTest.java @@ -39,17 +39,18 @@ public class DataTypeArchiveIDTest extends AbstractGenericTest { private static final String MAC_OS_10_9_GDT_PATH = "typeinfo/mac_10.9/mac_osx.gdt"; //@formatter:off - private static final Map archiveIdMap = Map.of( - WIN_VS12_32_GDT_PATH, "2644092282468053077", - WIN_VS12_64_GDT_PATH, "3193696833254024484", - GENERIC_CLIB_32_GDT_PATH, "2644097909188870631", - GENERIC_CLIB_64_GDT_PATH, "3193699959493190971", - MAC_OS_10_9_GDT_PATH, "2650667045259492112", - "typeinfo/golang/golang_1.17_anybit_any.gdt", "3533627828569507753", - "typeinfo/golang/golang_1.18_anybit_any.gdt", "3528902399865061936", - "typeinfo/golang/golang_1.19_anybit_any.gdt", "3533812166493410774", - "typeinfo/golang/golang_1.20_anybit_any.gdt", "3533817003441909616", - "typeinfo/rust/rust-common.gdt","3557867258392862055"); + private static final Map archiveIdMap = Map.ofEntries( + Map.entry(WIN_VS12_32_GDT_PATH, "2644092282468053077"), + Map.entry(WIN_VS12_64_GDT_PATH, "3193696833254024484"), + Map.entry(GENERIC_CLIB_32_GDT_PATH, "2644097909188870631"), + Map.entry(GENERIC_CLIB_64_GDT_PATH, "3193699959493190971"), + Map.entry(MAC_OS_10_9_GDT_PATH, "2650667045259492112"), + Map.entry("typeinfo/golang/golang_1.17_anybit_any.gdt", "3533627828569507753"), + Map.entry("typeinfo/golang/golang_1.18_anybit_any.gdt", "3528902399865061936"), + Map.entry("typeinfo/golang/golang_1.19_anybit_any.gdt", "3533812166493410774"), + Map.entry("typeinfo/golang/golang_1.20_anybit_any.gdt", "3533817003441909616"), + Map.entry("typeinfo/golang/golang_1.21_anybit_any.gdt", "3574190573109087960"), + Map.entry("typeinfo/rust/rust-common.gdt", "3557867258392862055")); //@formatter:on private Map getCurrentGdts() { diff --git a/Ghidra/Processors/x86/data/languages/x86-64-golang.register.info b/Ghidra/Processors/x86/data/languages/x86-64-golang.register.info index 11e51693e0..b9233453ad 100644 --- a/Ghidra/Processors/x86/data/languages/x86-64-golang.register.info +++ b/Ghidra/Processors/x86/data/languages/x86-64-golang.register.info @@ -1,6 +1,6 @@ - +