mirror of
https://github.com/thunderbrewhq/binana.git
synced 2025-12-12 01:42:29 +00:00
feat(binana): add check command for profiles
This commit is contained in:
parent
b5ddafb89a
commit
ebf88595d9
11 changed files with 151 additions and 39 deletions
4
go.mod
4
go.mod
|
|
@ -9,11 +9,15 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd // indirect
|
github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
lukechampine.com/uint128 v1.3.0 // indirect
|
lukechampine.com/uint128 v1.3.0 // indirect
|
||||||
modernc.org/mathutil v1.6.0 // indirect
|
modernc.org/mathutil v1.6.0 // indirect
|
||||||
modernc.org/strutil v1.2.0 // indirect
|
modernc.org/strutil v1.2.0 // indirect
|
||||||
|
|
|
||||||
11
go.sum
11
go.sum
|
|
@ -3,12 +3,19 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd h1:EVX1s+XNss9jkRW9K6XGJn2jL2lB1h5H804oKPsxOec=
|
github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd h1:EVX1s+XNss9jkRW9K6XGJn2jL2lB1h5H804oKPsxOec=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
|
github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
|
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
|
||||||
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||||
|
|
@ -20,6 +27,10 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
|
lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
|
||||||
|
|
|
||||||
97
go/cmd/binana/cmd/check.go
Normal file
97
go/cmd/binana/cmd/check.go
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/thunderbrewhq/binana/go/profile"
|
||||||
|
"github.com/thunderbrewhq/binana/go/symfile"
|
||||||
|
)
|
||||||
|
|
||||||
|
type check_params struct {
|
||||||
|
ProfileName string
|
||||||
|
Constructors bool
|
||||||
|
Bounds bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(params *check_params) {
|
||||||
|
p, err := profile.Open(params.ProfileName)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
named_function_count := uint64(0)
|
||||||
|
|
||||||
|
warnings := uint64(0)
|
||||||
|
|
||||||
|
warn := func(s *symfile.Entry, f string, args ...any) {
|
||||||
|
warnings++
|
||||||
|
color.Set(color.FgRed)
|
||||||
|
fmt.Printf(" warning: ")
|
||||||
|
color.Unset()
|
||||||
|
fmt.Printf("in line %d: (%s): ", s.LineNumber, s.Name)
|
||||||
|
fmt.Printf(f, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range p.SymbolTable.Entries {
|
||||||
|
sn := s.Name
|
||||||
|
|
||||||
|
if s.Kind == symfile.Function {
|
||||||
|
named_function_count++
|
||||||
|
|
||||||
|
if params.Constructors {
|
||||||
|
//
|
||||||
|
b, a, found := strings.Cut(sn, "__")
|
||||||
|
if found {
|
||||||
|
if b == a {
|
||||||
|
warn(&s, "this style of naming a constructor function is preferred: ClassName__constructor\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Bounds {
|
||||||
|
if s.EndAddress == 0 {
|
||||||
|
warn(&s, "does not have an end address\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Info.FunctionCount != 0 {
|
||||||
|
ratio := float64(named_function_count) / float64(p.Info.FunctionCount)
|
||||||
|
fmt.Printf("%d out of %d functions named (%f%%)\n", named_function_count, p.Info.FunctionCount, ratio*100.0)
|
||||||
|
fmt.Printf("%d warnings generated\n", warnings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func check_run(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
cmd.Help()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f := cmd.Flags()
|
||||||
|
var params check_params
|
||||||
|
params.ProfileName = args[0]
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
params.Constructors, err = f.GetBool("constructors")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
params.Bounds, err = f.GetBool("bounds")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
check(¶ms)
|
||||||
|
}
|
||||||
|
|
||||||
|
var check_cmd = cobra.Command{
|
||||||
|
Use: "check profile",
|
||||||
|
Short: "check a profile for correctness",
|
||||||
|
Run: check_run,
|
||||||
|
}
|
||||||
|
|
@ -81,12 +81,12 @@ func format_symbols(in io.Reader, out io.Writer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func format_symbols_func(cmd *cobra.Command, args []string) {
|
func format_symbols_run(cmd *cobra.Command, args []string) {
|
||||||
format_symbols(os.Stdin, os.Stdout)
|
format_symbols(os.Stdin, os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
var format_symbols_cmd = &cobra.Command{
|
var format_symbols_cmd = cobra.Command{
|
||||||
Use: "format-symbols",
|
Use: "format-symbols",
|
||||||
Short: "format symbols from stdin",
|
Short: "format symbols from stdin",
|
||||||
Run: format_symbols_func,
|
Run: format_symbols_run,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,7 @@ import (
|
||||||
"github.com/thunderbrewhq/binana/go/profile"
|
"github.com/thunderbrewhq/binana/go/profile"
|
||||||
)
|
)
|
||||||
|
|
||||||
var generate = &cobra.Command{
|
func generate_run(cmd *cobra.Command, args []string) {
|
||||||
Use: "generate",
|
|
||||||
Short: "Convert source files into various tool formats",
|
|
||||||
Run: generate_func,
|
|
||||||
}
|
|
||||||
|
|
||||||
func generate_func(cmd *cobra.Command, args []string) {
|
|
||||||
compress, err := cmd.Flags().GetBool("compress")
|
compress, err := cmd.Flags().GetBool("compress")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -35,3 +29,9 @@ func generate_func(cmd *cobra.Command, args []string) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var generate_cmd = cobra.Command{
|
||||||
|
Use: "generate",
|
||||||
|
Short: "Convert source files into various tool formats",
|
||||||
|
Run: generate_run,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands
|
// rootCmd represents the base command when called without any subcommands
|
||||||
var rootCmd = &cobra.Command{
|
var root = cobra.Command{
|
||||||
Use: "binana",
|
Use: "binana",
|
||||||
Short: "Binana helper tool",
|
Short: "Binana helper tool",
|
||||||
}
|
}
|
||||||
|
|
@ -18,27 +18,21 @@ var rootCmd = &cobra.Command{
|
||||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||||
func Execute() {
|
func Execute() {
|
||||||
err := rootCmd.Execute()
|
err := root.Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Here you will define your flags and configuration settings.
|
generate_cmd.Flags().StringP("profile", "p", "3.3.5a", "the game profile")
|
||||||
// Cobra supports persistent flags, which, if defined here,
|
generate_cmd.Flags().BoolP("compress", "c", true, "enable/disable compression of the x64dbg database file")
|
||||||
// will be global for your application.
|
|
||||||
|
|
||||||
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.binana.yaml)")
|
check_cmd.Flags().Bool("bounds", false, "check for bad function boundaries")
|
||||||
|
check_cmd.Flags().Bool("constructors", false, "check for outdated class constructor names")
|
||||||
|
|
||||||
// Cobra also supports local flags, which will only run
|
root.AddCommand(&generate_cmd)
|
||||||
// when this action is called directly.
|
root.AddCommand(&format_symbols_cmd)
|
||||||
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
root.AddCommand(&x64dbg_typesort_cmd)
|
||||||
|
root.AddCommand(&check_cmd)
|
||||||
generate.Flags().StringP("profile", "p", "3.3.5a", "the game profile")
|
|
||||||
generate.Flags().BoolP("compress", "c", true, "enable/disable compression of the x64dbg database file")
|
|
||||||
|
|
||||||
rootCmd.AddCommand(generate)
|
|
||||||
rootCmd.AddCommand(format_symbols_cmd)
|
|
||||||
rootCmd.AddCommand(x64dbg_typesort)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ import (
|
||||||
"github.com/thunderbrewhq/binana/go/x64dbg"
|
"github.com/thunderbrewhq/binana/go/x64dbg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var x64dbg_typesort = &cobra.Command{
|
var x64dbg_typesort_cmd = cobra.Command{
|
||||||
Use: "x64dbg-typesort [types.json file]",
|
Use: "x64dbg-typesort [types.json file]",
|
||||||
Short: "sort a x64dbg types file",
|
Short: "sort a x64dbg types file",
|
||||||
Run: x64dbg_typesort_func,
|
Run: x64dbg_typesort_run,
|
||||||
}
|
}
|
||||||
|
|
||||||
func x64dbg_typesort_func(cmd *cobra.Command, args []string) {
|
func x64dbg_typesort_run(cmd *cobra.Command, args []string) {
|
||||||
types, err := x64dbg.LoadTypes(args[0])
|
types, err := x64dbg.LoadTypes(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
||||||
|
|
@ -23,17 +23,19 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type info_schema struct {
|
type info_schema struct {
|
||||||
OS string `json:"os"`
|
OS string `json:"os"`
|
||||||
Arch string `json:"arch"`
|
Arch string `json:"arch"`
|
||||||
ModuleName string `json:"module_name"`
|
ModuleName string `json:"module_name"`
|
||||||
ModuleBase string `json:"module_base"`
|
ModuleBase string `json:"module_base"`
|
||||||
|
FunctionCount uint64 `json:"function_count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Info struct {
|
type Info struct {
|
||||||
OS string
|
OS string
|
||||||
Arch string
|
Arch string
|
||||||
ModuleName string
|
ModuleName string
|
||||||
ModuleBase uint64
|
ModuleBase uint64
|
||||||
|
FunctionCount uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func read_info(filename string, info *Info) (err error) {
|
func read_info(filename string, info *Info) (err error) {
|
||||||
|
|
@ -68,5 +70,7 @@ func read_info(filename string, info *Info) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.FunctionCount = is.FunctionCount
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ func (profile *Profile) generate_x64dbg_database(compress bool) (err error) {
|
||||||
relative_end_address -= 1
|
relative_end_address -= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if relative_end_address < relative_start_address || relative_end_address-relative_start_address >= 10000 {
|
if relative_end_address < relative_start_address || relative_end_address-relative_start_address >= 50000 {
|
||||||
fmt.Printf("Strange symbol %s %08x %08x (offset %d)\n", entry.Name, relative_start_address, relative_end_address, relative_end_address-relative_start_address)
|
fmt.Printf("Strange symbol %s %08x %08x (offset %d)\n", entry.Name, relative_start_address, relative_end_address, relative_end_address-relative_start_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const min_columns = 3
|
||||||
type loader struct {
|
type loader struct {
|
||||||
input *bufio.Reader
|
input *bufio.Reader
|
||||||
table Table
|
table Table
|
||||||
line_number int
|
line_number uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loader) read_line() (line string, err error) {
|
func (l *loader) read_line() (line string, err error) {
|
||||||
|
|
@ -32,6 +32,7 @@ func (l *loader) parse_line(line string) (err error) {
|
||||||
err = fmt.Errorf("%w: line %d", err, l.line_number)
|
err = fmt.Errorf("%w: line %d", err, l.line_number)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
entry.LineNumber = l.line_number
|
||||||
|
|
||||||
err = l.table.Insert(&entry)
|
err = l.table.Insert(&entry)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ var (
|
||||||
|
|
||||||
// An entry in the table
|
// An entry in the table
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
|
LineNumber uint64
|
||||||
// Undecorated, raw name
|
// Undecorated, raw name
|
||||||
Name string
|
Name string
|
||||||
// Offset to the start of the function or data
|
// Offset to the start of the function or data
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue