mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-10 06:09:20 +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.24.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.16_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>
|
||||
* Similar to {@link NoteGoBuildId}, but re-implemented here because of the different
|
||||
* serialization used.
|
||||
*
|
||||
* TODO: stop using 83 byte fixed len for buildid string, use leading / trailing quotes
|
||||
*/
|
||||
public class GoBuildId {
|
||||
private static final byte[] GO_BUILDID_MAGIC =
|
||||
"\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;
|
||||
|
||||
public static ItemWithAddress<GoBuildId> findBuildId(Program program) {
|
||||
@@ -64,7 +68,14 @@ public class GoBuildId {
|
||||
if (!Arrays.equals(magic, GO_BUILDID_MAGIC)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -81,7 +92,8 @@ public class GoBuildId {
|
||||
* @return GoBuildId instance, or null if not present
|
||||
*/
|
||||
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 {
|
||||
int bytesRead = is.read(buffer);
|
||||
if (bytesRead == buffer.length) {
|
||||
@@ -127,6 +139,8 @@ public class GoBuildId {
|
||||
new StructureDataType(GoConstants.GOLANG_CATEGORYPATH, "GoBuildId", 0, dtm);
|
||||
result.add(StringDataType.dataType, GO_BUILDID_MAGIC.length, "magic", null);
|
||||
result.add(StringDataType.dataType, BUILDID_STR_LEN, "buildId", null);
|
||||
result.add(StringDataType.dataType, GO_BUIlDID_TRAILING_MAGIC.length, "trailing_magic",
|
||||
null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+9
-6
@@ -412,14 +412,17 @@ public class GoModuledata implements StructureMarkup<GoModuledata> {
|
||||
* @return new GoModuledata instance, or null if not found
|
||||
* @throws IOException if error reading found structure
|
||||
*/
|
||||
/* package */ static GoModuledata getFirstModuledata(GoRttiMapper context)
|
||||
throws IOException {
|
||||
/* package */ static GoModuledata getFirstModuledata(GoRttiMapper context) throws IOException {
|
||||
Program program = context.getProgram();
|
||||
Symbol firstModuleDataSymbol = GoRttiMapper.getGoSymbol(program, "runtime.firstmoduledata");
|
||||
if (firstModuleDataSymbol == null) {
|
||||
return null;
|
||||
MemoryBlock memblk = context.getGoSection("go.module");
|
||||
if (memblk != 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
|
||||
private byte ptrSize;
|
||||
|
||||
@FieldMapping(presentWhen = "1.18+")
|
||||
@FieldMapping(presentWhen = "1.18-1.25")
|
||||
@MarkupReference
|
||||
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}
|
||||
*/
|
||||
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>
|
||||
*/
|
||||
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> SECTION_PREFIXES =
|
||||
|
||||
+5
-3
@@ -83,7 +83,7 @@ public class GoBaseType implements StructureVerifier {
|
||||
* {@return the {@link GoTypeFlag}s assigned to this type definition}
|
||||
*/
|
||||
public Set<GoTypeFlag> getFlags() {
|
||||
return GoTypeFlag.parseFlags(tflag);
|
||||
return GoTypeFlag.parseFlags(tflag, programContext.getGoVer());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,7 +98,7 @@ public class GoBaseType implements StructureVerifier {
|
||||
* structure}
|
||||
*/
|
||||
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() {
|
||||
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")
|
||||
private long elem; // ptr to type
|
||||
|
||||
@FieldMapping
|
||||
@FieldMapping(presentWhen = "-1.25")
|
||||
@MarkupReference("getBucket")
|
||||
private long bucket; // ptr to type
|
||||
|
||||
@FieldMapping(presentWhen = "1.26-")
|
||||
@MarkupReference("getGroup")
|
||||
private long group; // ptr to group type
|
||||
|
||||
@FieldMapping
|
||||
private long hasher; // pointer to "func(Pointer, pointer) pointer"
|
||||
|
||||
@FieldMapping
|
||||
@FieldMapping(presentWhen = "-1.25")
|
||||
private int keysize;
|
||||
|
||||
@FieldMapping(fieldName = {"elemsize", "ValueSize"})
|
||||
@FieldMapping(fieldName = { "elemsize", "ValueSize" }, presentWhen = "-1.25")
|
||||
private int elemsize;
|
||||
|
||||
@FieldMapping
|
||||
@FieldMapping(presentWhen = "-1.25")
|
||||
private int bucketsize;
|
||||
|
||||
@FieldMapping
|
||||
@@ -95,7 +99,18 @@ public class GoMapType extends GoType {
|
||||
*/
|
||||
@Markup
|
||||
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
|
||||
|
||||
+24
-12
@@ -26,11 +26,16 @@ import ghidra.app.util.bin.format.golang.GoVerRange;
|
||||
*/
|
||||
public enum GoTypeFlag {
|
||||
|
||||
Uncommon(1 << 0, GoVerRange.ALL), // 1
|
||||
ExtraStar(1 << 1, GoVerRange.ALL), // 2
|
||||
Named(1 << 2, GoVerRange.ALL), // 4
|
||||
RegularMemory(1 << 3, GoVerRange.ALL), // 8
|
||||
UnrolledBitmap(1 << 4, GoVerRange.parse("1.22-")); // 16
|
||||
Uncommon(1 << 0, GoVerRange.ALL), // 1
|
||||
ExtraStar(1 << 1, GoVerRange.ALL), // 2
|
||||
Named(1 << 2, GoVerRange.ALL), // 4
|
||||
RegularMemory(1 << 3, GoVerRange.ALL), // 8
|
||||
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 GoVerRange validVersions;
|
||||
@@ -44,8 +49,16 @@ public enum GoTypeFlag {
|
||||
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();
|
||||
|
||||
public static boolean isValid(int b, GoVer ver) {
|
||||
int maxMask = 0;
|
||||
for (GoTypeFlag flag : lookupvalues) {
|
||||
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);
|
||||
for (GoTypeFlag flag : lookupvalues) {
|
||||
if (flag.isSet(b)) {
|
||||
if (flag.isSet(b, ver)) {
|
||||
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
|
||||
* 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
|
||||
* @return path to newly created goroot directory (under the workDir)
|
||||
* @throws IOException if failure
|
||||
*/
|
||||
File createVersionedGoRoot(GoVer ver)
|
||||
throws IOException {
|
||||
File createVersionedGoRoot(GoVer ver) throws IOException {
|
||||
String verTagName = getGoRepoTagName(GOLANG_REPO_DIR, ver);
|
||||
|
||||
execGitCmd(GOLANG_REPO_DIR, null, "checkout", "-q", verTagName);
|
||||
|
||||
Reference in New Issue
Block a user