Various arch fixes for Go dumping (#3128)

pull/3131/head
Jason An 6 months ago committed by GitHub
parent a6cf06b8cf
commit c82fbcd11f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -51,16 +51,48 @@ def word_size() -> int:
""" """
Gets the Go word size for the current architecture. Gets the Go word size for the current architecture.
Values taken from https://github.com/golang/go/blob/20b79fd5775c39061d949569743912ad5e58b0e7/src/go/types/sizes.go#L233-L252 Values taken from https://github.com/golang/go/blob/49cdf0c42e320dfed044baa551610f081eafb781/src/cmd/compile/internal/types2/sizes.go#L230-L249
""" """
return { return {
"i386": 4,
"x86-64": 8, "x86-64": 8,
"aarch64": 8, "i386": 4,
# Go cannot target i8086
"arm": 4, "arm": 4,
# Go cannot target armcm
"aarch64": 8,
"powerpc": 8,
"sparc": 8,
# Go cannot target rv32 (but gccgo can)
"rv64": 8, "rv64": 8,
"mips": pwndbg.aglib.arch.ptrsize, # pwndbg uses mips for both 32 and 64 bit
"loongarch64": 8,
"s390x": 8,
}[pwndbg.aglib.arch.name]
@pwndbg.lib.cache.cache_until("start", "stop", "objfile")
def max_align() -> int:
"""
Gets the Go maximum alignment for the current architecture.
Values taken from https://github.com/golang/go/blob/49cdf0c42e320dfed044baa551610f081eafb781/src/cmd/compile/internal/types2/sizes.go#L230-L249
"""
# Note: gccgo has max alignment 8 for arm and mips, which is different from the default compiler
# Currently, no attempt is made to support gccgo, but it may be worth pursuing in the future
return {
"x86-64": 8,
"i386": 4,
# Go cannot target i8086
"arm": 4,
# Go cannot target armcm
"aarch64": 8,
"powerpc": 8, "powerpc": 8,
"sparc": 8, "sparc": 8,
# Go cannot target rv32 (but gccgo can)
"rv64": 8,
"mips": pwndbg.aglib.arch.ptrsize, # pwndbg uses mips for both 32 and 64 bit
"loongarch64": 8,
"s390x": 8,
}[pwndbg.aglib.arch.name] }[pwndbg.aglib.arch.name]
@ -828,7 +860,7 @@ class BasicType(Type):
return self.sz return self.sz
def align(self) -> int: def align(self) -> int:
return self.algn return min(self.algn, max_align())
def get_typename(self) -> str: def get_typename(self) -> str:
return self.name return self.name
@ -932,7 +964,7 @@ class PointerType(Type):
return word_size() return word_size()
def align(self) -> int: def align(self) -> int:
return word_size() return min(word_size(), max_align())
def get_typename(self) -> str: def get_typename(self) -> str:
return f"*{self.inner}" return f"*{self.inner}"
@ -1216,7 +1248,7 @@ class MapType(Type):
return self.field_offsets()["$size"] return self.field_offsets()["$size"]
def align(self) -> int: def align(self) -> int:
return 8 return min(8, max_align())
def get_typename(self) -> str: def get_typename(self) -> str:
return f"map[{self.key}]{self.val}" return f"map[{self.key}]{self.val}"
@ -1266,7 +1298,9 @@ class StructType(Type):
def align(self) -> int: def align(self) -> int:
if self.algn is None: if self.algn is None:
return max(ty.align() for (_, ty, _) in self.fields if isinstance(ty, Type)) return max(
(ty.align() for (_, ty, _) in self.fields if isinstance(ty, Type)), default=1
)
return self.algn return self.algn
def get_typename(self) -> str: def get_typename(self) -> str:

@ -8,6 +8,7 @@ func testFunc(x interface{}) *interface{} {
} }
func main() { func main() {
testFunc(map[uint8]uint64{1: 2, 3: 4, 5: 6})
testFunc(map[string]int{"a": 1, "b": 2, "c": 3}) testFunc(map[string]int{"a": 1, "b": 2, "c": 3})
testFunc([]struct { testFunc([]struct {
a int a int

@ -35,17 +35,24 @@ def helper_test_dump(start_binary, filename):
start_binary(filename) start_binary(filename)
gdb.execute("break gosample.go:6", to_string=True) gdb.execute("break gosample.go:6", to_string=True)
gdb.execute("continue") gdb.execute("continue")
first = gdb.execute("go-dump any &x", to_string=True)
assert first.strip() == """(map[string]int) &{"a": 1, "b": 2, "c": 3}""" dump = gdb.execute("go-dump any &x", to_string=True)
assert dump.strip() == """(map[uint8]uint64) &{1: 2, 3: 4, 5: 6}"""
gdb.execute("continue")
dump = gdb.execute("go-dump any &x", to_string=True)
assert dump.strip() == """(map[string]int) &{"a": 1, "b": 2, "c": 3}"""
gdb.execute("continue") gdb.execute("continue")
second = gdb.execute("go-dump any &x", to_string=True)
dump = gdb.execute("go-dump any &x", to_string=True)
assert ( assert (
second.strip() dump.strip()
== """([]struct { a int; b string }) [struct {a: 1, b: "first"}, struct {a: 2, b: "second"}]""" == """([]struct { a int; b string }) [struct {a: 1, b: "first"}, struct {a: 2, b: "second"}]"""
) )
gdb.execute("continue") gdb.execute("continue")
third = gdb.execute("go-dump -f 1 any &x", to_string=True)
assert third.strip() == """([3]complex64) [(1.1 + 2.2i), (-2.5 - 5.0i), (4.2 - 2.1i)]""" dump = gdb.execute("go-dump -f 1 any &x", to_string=True)
assert dump.strip() == """([3]complex64) [(1.1 + 2.2i), (-2.5 - 5.0i), (4.2 - 2.1i)]"""
def test_go_dumping_x64(start_binary): def test_go_dumping_x64(start_binary):

Loading…
Cancel
Save