mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-01 07:55:05 +08:00
Merge remote-tracking branch 'origin/GP-6528_dev747368_golang_1.26'
(Closes #9013)
This commit is contained in:
@@ -102,6 +102,7 @@ data/typeinfo/golang/go1.22.0.json||GHIDRA||||END|
|
|||||||
data/typeinfo/golang/go1.23.0.json||GHIDRA||||END|
|
data/typeinfo/golang/go1.23.0.json||GHIDRA||||END|
|
||||||
data/typeinfo/golang/go1.24.0.json||GHIDRA||||END|
|
data/typeinfo/golang/go1.24.0.json||GHIDRA||||END|
|
||||||
data/typeinfo/golang/go1.25.0.json||GHIDRA||||END|
|
data/typeinfo/golang/go1.25.0.json||GHIDRA||||END|
|
||||||
|
data/typeinfo/golang/go1.26.0.json||GHIDRA||||END|
|
||||||
data/typeinfo/golang/golang_1.15_anybit_any.gdt||GHIDRA||||END|
|
data/typeinfo/golang/golang_1.15_anybit_any.gdt||GHIDRA||||END|
|
||||||
data/typeinfo/golang/golang_1.16_anybit_any.gdt||GHIDRA||||END|
|
data/typeinfo/golang/golang_1.16_anybit_any.gdt||GHIDRA||||END|
|
||||||
data/typeinfo/golang/golang_1.17_anybit_any.gdt||GHIDRA||||END|
|
data/typeinfo/golang/golang_1.17_anybit_any.gdt||GHIDRA||||END|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+15
-1
@@ -37,10 +37,14 @@ import ghidra.util.Msg;
|
|||||||
* <p>
|
* <p>
|
||||||
* Similar to {@link NoteGoBuildId}, but re-implemented here because of the different
|
* Similar to {@link NoteGoBuildId}, but re-implemented here because of the different
|
||||||
* serialization used.
|
* serialization used.
|
||||||
|
*
|
||||||
|
* TODO: stop using 83 byte fixed len for buildid string, use leading / trailing quotes
|
||||||
*/
|
*/
|
||||||
public class GoBuildId {
|
public class GoBuildId {
|
||||||
private static final byte[] GO_BUILDID_MAGIC =
|
private static final byte[] GO_BUILDID_MAGIC =
|
||||||
"\u00ff Go build ID: \"".getBytes(StandardCharsets.ISO_8859_1);
|
"\u00ff Go build ID: \"".getBytes(StandardCharsets.ISO_8859_1);
|
||||||
|
private static final byte[] GO_BUIlDID_TRAILING_MAGIC =
|
||||||
|
"\"\n \u00ff".getBytes(StandardCharsets.ISO_8859_1);
|
||||||
private static final int BUILDID_STR_LEN = 83;
|
private static final int BUILDID_STR_LEN = 83;
|
||||||
|
|
||||||
public static ItemWithAddress<GoBuildId> findBuildId(Program program) {
|
public static ItemWithAddress<GoBuildId> findBuildId(Program program) {
|
||||||
@@ -64,7 +68,14 @@ public class GoBuildId {
|
|||||||
if (!Arrays.equals(magic, GO_BUILDID_MAGIC)) {
|
if (!Arrays.equals(magic, GO_BUILDID_MAGIC)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String buildIdStr = br.readNextAsciiString(BUILDID_STR_LEN);
|
String buildIdStr = br.readNextAsciiString(BUILDID_STR_LEN);
|
||||||
|
|
||||||
|
byte[] trailingMagic = br.readNextByteArray(GO_BUIlDID_TRAILING_MAGIC.length);
|
||||||
|
if (!Arrays.equals(trailingMagic, GO_BUIlDID_TRAILING_MAGIC)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new GoBuildId(buildIdStr);
|
return new GoBuildId(buildIdStr);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
@@ -81,7 +92,8 @@ public class GoBuildId {
|
|||||||
* @return GoBuildId instance, or null if not present
|
* @return GoBuildId instance, or null if not present
|
||||||
*/
|
*/
|
||||||
public static GoBuildId read(InputStream is) {
|
public static GoBuildId read(InputStream is) {
|
||||||
byte[] buffer = new byte[GO_BUILDID_MAGIC.length + BUILDID_STR_LEN];
|
byte[] buffer =
|
||||||
|
new byte[GO_BUILDID_MAGIC.length + BUILDID_STR_LEN + GO_BUIlDID_TRAILING_MAGIC.length];
|
||||||
try {
|
try {
|
||||||
int bytesRead = is.read(buffer);
|
int bytesRead = is.read(buffer);
|
||||||
if (bytesRead == buffer.length) {
|
if (bytesRead == buffer.length) {
|
||||||
@@ -127,6 +139,8 @@ public class GoBuildId {
|
|||||||
new StructureDataType(GoConstants.GOLANG_CATEGORYPATH, "GoBuildId", 0, dtm);
|
new StructureDataType(GoConstants.GOLANG_CATEGORYPATH, "GoBuildId", 0, dtm);
|
||||||
result.add(StringDataType.dataType, GO_BUILDID_MAGIC.length, "magic", null);
|
result.add(StringDataType.dataType, GO_BUILDID_MAGIC.length, "magic", null);
|
||||||
result.add(StringDataType.dataType, BUILDID_STR_LEN, "buildId", null);
|
result.add(StringDataType.dataType, BUILDID_STR_LEN, "buildId", null);
|
||||||
|
result.add(StringDataType.dataType, GO_BUIlDID_TRAILING_MAGIC.length, "trailing_magic",
|
||||||
|
null);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-6
@@ -412,14 +412,17 @@ public class GoModuledata implements StructureMarkup<GoModuledata> {
|
|||||||
* @return new GoModuledata instance, or null if not found
|
* @return new GoModuledata instance, or null if not found
|
||||||
* @throws IOException if error reading found structure
|
* @throws IOException if error reading found structure
|
||||||
*/
|
*/
|
||||||
/* package */ static GoModuledata getFirstModuledata(GoRttiMapper context)
|
/* package */ static GoModuledata getFirstModuledata(GoRttiMapper context) throws IOException {
|
||||||
throws IOException {
|
|
||||||
Program program = context.getProgram();
|
Program program = context.getProgram();
|
||||||
Symbol firstModuleDataSymbol = GoRttiMapper.getGoSymbol(program, "runtime.firstmoduledata");
|
MemoryBlock memblk = context.getGoSection("go.module");
|
||||||
if (firstModuleDataSymbol == null) {
|
if (memblk != null) {
|
||||||
return null;
|
return context.readStructure(GoModuledata.class, memblk.getStart());
|
||||||
}
|
}
|
||||||
return context.readStructure(GoModuledata.class, firstModuleDataSymbol.getAddress());
|
Symbol firstModuleDataSymbol = GoRttiMapper.getGoSymbol(program, "runtime.firstmoduledata");
|
||||||
|
if (firstModuleDataSymbol != null) {
|
||||||
|
return context.readStructure(GoModuledata.class, firstModuleDataSymbol.getAddress());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-2
@@ -177,7 +177,7 @@ public class GoPcHeader {
|
|||||||
@FieldMapping
|
@FieldMapping
|
||||||
private byte ptrSize;
|
private byte ptrSize;
|
||||||
|
|
||||||
@FieldMapping(presentWhen = "1.18+")
|
@FieldMapping(presentWhen = "1.18-1.25")
|
||||||
@MarkupReference
|
@MarkupReference
|
||||||
private long textStart; // should be same as offset of ".text"
|
private long textStart; // should be same as offset of ".text"
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ public class GoPcHeader {
|
|||||||
* {@return the address of where the text area starts}
|
* {@return the address of where the text area starts}
|
||||||
*/
|
*/
|
||||||
public Address getTextStart() {
|
public Address getTextStart() {
|
||||||
return programContext.getDataAddress(textStart);
|
return textStart != 0 ? programContext.getDataAddress(textStart) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -76,7 +76,7 @@ import ghidra.util.task.UnknownProgressWrappingTaskMonitor;
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public class GoRttiMapper extends DataTypeMapper implements DataTypeMapperContext {
|
public class GoRttiMapper extends DataTypeMapper implements DataTypeMapperContext {
|
||||||
public static final GoVerRange SUPPORTED_VERSIONS = GoVerRange.parse("1.15-1.25");
|
public static final GoVerRange SUPPORTED_VERSIONS = GoVerRange.parse("1.15-1.26");
|
||||||
|
|
||||||
private static final List<String> SYMBOL_SEARCH_PREFIXES = List.of("", "_" /* macho symbols */);
|
private static final List<String> SYMBOL_SEARCH_PREFIXES = List.of("", "_" /* macho symbols */);
|
||||||
private static final List<String> SECTION_PREFIXES =
|
private static final List<String> SECTION_PREFIXES =
|
||||||
|
|||||||
+5
-3
@@ -83,7 +83,7 @@ public class GoBaseType implements StructureVerifier {
|
|||||||
* {@return the {@link GoTypeFlag}s assigned to this type definition}
|
* {@return the {@link GoTypeFlag}s assigned to this type definition}
|
||||||
*/
|
*/
|
||||||
public Set<GoTypeFlag> getFlags() {
|
public Set<GoTypeFlag> getFlags() {
|
||||||
return GoTypeFlag.parseFlags(tflag);
|
return GoTypeFlag.parseFlags(tflag, programContext.getGoVer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,7 +98,7 @@ public class GoBaseType implements StructureVerifier {
|
|||||||
* structure}
|
* structure}
|
||||||
*/
|
*/
|
||||||
public boolean hasUncommonType() {
|
public boolean hasUncommonType() {
|
||||||
return GoTypeFlag.Uncommon.isSet(tflag);
|
return GoTypeFlag.Uncommon.isSet(tflag, programContext.getGoVer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +115,9 @@ public class GoBaseType implements StructureVerifier {
|
|||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
String s = programContext.getSafeName(this::getGoName, this, "").getName();
|
String s = programContext.getSafeName(this::getGoName, this, "").getName();
|
||||||
return GoTypeFlag.ExtraStar.isSet(tflag) && s.startsWith("*") ? s.substring(1) : s;
|
return GoTypeFlag.ExtraStar.isSet(tflag, programContext.getGoVer()) && s.startsWith("*")
|
||||||
|
? s.substring(1)
|
||||||
|
: s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+20
-5
@@ -42,20 +42,24 @@ public class GoMapType extends GoType {
|
|||||||
@MarkupReference("getElement")
|
@MarkupReference("getElement")
|
||||||
private long elem; // ptr to type
|
private long elem; // ptr to type
|
||||||
|
|
||||||
@FieldMapping
|
@FieldMapping(presentWhen = "-1.25")
|
||||||
@MarkupReference("getBucket")
|
@MarkupReference("getBucket")
|
||||||
private long bucket; // ptr to type
|
private long bucket; // ptr to type
|
||||||
|
|
||||||
|
@FieldMapping(presentWhen = "1.26-")
|
||||||
|
@MarkupReference("getGroup")
|
||||||
|
private long group; // ptr to group type
|
||||||
|
|
||||||
@FieldMapping
|
@FieldMapping
|
||||||
private long hasher; // pointer to "func(Pointer, pointer) pointer"
|
private long hasher; // pointer to "func(Pointer, pointer) pointer"
|
||||||
|
|
||||||
@FieldMapping
|
@FieldMapping(presentWhen = "-1.25")
|
||||||
private int keysize;
|
private int keysize;
|
||||||
|
|
||||||
@FieldMapping(fieldName = {"elemsize", "ValueSize"})
|
@FieldMapping(fieldName = { "elemsize", "ValueSize" }, presentWhen = "-1.25")
|
||||||
private int elemsize;
|
private int elemsize;
|
||||||
|
|
||||||
@FieldMapping
|
@FieldMapping(presentWhen = "-1.25")
|
||||||
private int bucketsize;
|
private int bucketsize;
|
||||||
|
|
||||||
@FieldMapping
|
@FieldMapping
|
||||||
@@ -95,7 +99,18 @@ public class GoMapType extends GoType {
|
|||||||
*/
|
*/
|
||||||
@Markup
|
@Markup
|
||||||
public GoType getBucket() throws IOException {
|
public GoType getBucket() throws IOException {
|
||||||
return programContext.getGoTypes().getType(bucket);
|
return bucket != 0 ? programContext.getGoTypes().getType(bucket) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the GoType that defines the map's group, referenced by the group field's markup annotation
|
||||||
|
*
|
||||||
|
* @return GoType that defines the map's group
|
||||||
|
* @throws IOException if error reading data
|
||||||
|
*/
|
||||||
|
@Markup
|
||||||
|
public GoType getGroup() throws IOException {
|
||||||
|
return group != 0 ? programContext.getGoTypes().getType(group) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+24
-12
@@ -26,11 +26,16 @@ import ghidra.app.util.bin.format.golang.GoVerRange;
|
|||||||
*/
|
*/
|
||||||
public enum GoTypeFlag {
|
public enum GoTypeFlag {
|
||||||
|
|
||||||
Uncommon(1 << 0, GoVerRange.ALL), // 1
|
Uncommon(1 << 0, GoVerRange.ALL), // 1
|
||||||
ExtraStar(1 << 1, GoVerRange.ALL), // 2
|
ExtraStar(1 << 1, GoVerRange.ALL), // 2
|
||||||
Named(1 << 2, GoVerRange.ALL), // 4
|
Named(1 << 2, GoVerRange.ALL), // 4
|
||||||
RegularMemory(1 << 3, GoVerRange.ALL), // 8
|
RegularMemory(1 << 3, GoVerRange.ALL), // 8
|
||||||
UnrolledBitmap(1 << 4, GoVerRange.parse("1.22-")); // 16
|
UnrolledBitmap(1 << 4, GoVerRange.parse("1.22-1.23")), // 16
|
||||||
|
GCMaskOnDemand(1 << 4, GoVerRange.parse("1.24-")), // 16
|
||||||
|
|
||||||
|
// FUTURE: "value of this type is stored directly in the data field of an interface instead of
|
||||||
|
// indirectly", same as testing Size_ == PtrBytes == goarch.PtrSize
|
||||||
|
DirectIFace(1 << 5, GoVerRange.parse("1.24-")); // 32
|
||||||
|
|
||||||
private final int value;
|
private final int value;
|
||||||
private GoVerRange validVersions;
|
private GoVerRange validVersions;
|
||||||
@@ -44,8 +49,16 @@ public enum GoTypeFlag {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSet(int i) {
|
/**
|
||||||
return (i & value) != 0;
|
* Returns true if this enum instance is set in the supplied integer
|
||||||
|
* (for the specified go version)
|
||||||
|
*
|
||||||
|
* @param i int packed flag
|
||||||
|
* @param ver version of this binary
|
||||||
|
* @return boolean true if this flag is set
|
||||||
|
*/
|
||||||
|
public boolean isSet(int i, GoVer ver) {
|
||||||
|
return validVersions.contains(ver) && (i & value) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@@ -53,19 +66,18 @@ public enum GoTypeFlag {
|
|||||||
private static final GoTypeFlag[] lookupvalues = values();
|
private static final GoTypeFlag[] lookupvalues = values();
|
||||||
|
|
||||||
public static boolean isValid(int b, GoVer ver) {
|
public static boolean isValid(int b, GoVer ver) {
|
||||||
int maxMask = 0;
|
|
||||||
for (GoTypeFlag flag : lookupvalues) {
|
for (GoTypeFlag flag : lookupvalues) {
|
||||||
if (flag.validVersions.contains(ver)) {
|
if (flag.validVersions.contains(ver)) {
|
||||||
maxMask |= flag.value;
|
b &= ~flag.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return b <= maxMask;
|
return b == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<GoTypeFlag> parseFlags(int b) {
|
public static Set<GoTypeFlag> parseFlags(int b, GoVer ver) {
|
||||||
EnumSet<GoTypeFlag> result = EnumSet.noneOf(GoTypeFlag.class);
|
EnumSet<GoTypeFlag> result = EnumSet.noneOf(GoTypeFlag.class);
|
||||||
for (GoTypeFlag flag : lookupvalues) {
|
for (GoTypeFlag flag : lookupvalues) {
|
||||||
if (flag.isSet(b)) {
|
if (flag.isSet(b, ver)) {
|
||||||
result.add(flag);
|
result.add(flag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -331,14 +331,11 @@ public class GoApiSnapshotGeneratorTest extends AbstractGenericTest {
|
|||||||
* Build a frankenstein goroot directory using the guts of a go install (liveGoRoot) and
|
* Build a frankenstein goroot directory using the guts of a go install (liveGoRoot) and
|
||||||
* the src directory from a specific tagged version of a go git repo directory.
|
* the src directory from a specific tagged version of a go git repo directory.
|
||||||
*
|
*
|
||||||
* @param goRepoDir path to a golang git repo
|
|
||||||
* @param liveGoRoot path to an installed golang instance
|
|
||||||
* @param ver go version to checkout from the git repo and copy to the new directory
|
* @param ver go version to checkout from the git repo and copy to the new directory
|
||||||
* @return path to newly created goroot directory (under the workDir)
|
* @return path to newly created goroot directory (under the workDir)
|
||||||
* @throws IOException if failure
|
* @throws IOException if failure
|
||||||
*/
|
*/
|
||||||
File createVersionedGoRoot(GoVer ver)
|
File createVersionedGoRoot(GoVer ver) throws IOException {
|
||||||
throws IOException {
|
|
||||||
String verTagName = getGoRepoTagName(GOLANG_REPO_DIR, ver);
|
String verTagName = getGoRepoTagName(GOLANG_REPO_DIR, ver);
|
||||||
|
|
||||||
execGitCmd(GOLANG_REPO_DIR, null, "checkout", "-q", verTagName);
|
execGitCmd(GOLANG_REPO_DIR, null, "checkout", "-q", verTagName);
|
||||||
|
|||||||
Reference in New Issue
Block a user