xtool/nm:symbol version

This commit is contained in:
luoliwoshang
2024-10-15 14:48:51 +08:00
parent ace3c3e421
commit d682771c35
2 changed files with 50 additions and 8 deletions

View File

@@ -22,6 +22,7 @@ import (
"os"
"github.com/goplus/llgo/xtool/env/llvm"
nmtool "github.com/goplus/llgo/xtool/nm"
)
func main() {
@@ -45,10 +46,17 @@ func main() {
fmt.Printf("\n%s:\n", item.File)
}
for _, sym := range item.Symbols {
var versionInfo string
switch sym.VersionType {
case nmtool.VersionSpecific:
versionInfo = fmt.Sprintf("@%s", sym.Version)
case nmtool.VersionDefault:
versionInfo = fmt.Sprintf("@@%s", sym.Version)
}
if sym.FAddr {
fmt.Printf("%016x %c %s\n", sym.Addr, sym.Type, sym.Name)
fmt.Printf("%016x %c %s%s\n", sym.Addr, sym.Type, sym.Name, versionInfo)
} else {
fmt.Printf("%16s %c %s\n", "", sym.Type, sym.Name)
fmt.Printf("%16s %c %s%s\n", "", sym.Type, sym.Name, versionInfo)
}
}
}

View File

@@ -62,12 +62,26 @@ const (
LocalASym = SymbolType('s') // Local symbol in an assembler source file
)
// VersionType represents the version type of a symbol.
// This is specific to Linux systems.
// On macOS , this will always be VersionNone.
// https://sourceware.org/binutils/docs/binutils/nm.html
type VersionType int
const (
VersionNone VersionType = iota // No version information
VersionSpecific // Specific version (@)
VersionDefault // Default version (@@)
)
// Symbol represents a symbol in an object file.
type Symbol struct {
Name string // symbol name
Addr uint64 // symbol address
Type SymbolType // symbol type
FAddr bool // address is valid
Name string // symbol name
Addr uint64 // symbol address
Type SymbolType // symbol type
FAddr bool // address is valid
VersionType VersionType // version type of the symbol
Version string // version information of the symbol
}
// ObjectFile represents an object file.
@@ -143,28 +157,48 @@ func listOutput(data []byte) (items []*ObjectFile, err error) {
return
}
var sym *Symbol
var fullSymName string
if is64bits(line) {
fullSymName = string(line[19:])
sym = &Symbol{
Name: string(line[19:]),
Type: SymbolType(line[17]),
}
if sym.FAddr = hasAddr(line); sym.FAddr {
sym.Addr = hexUint64(line)
}
} else {
fullSymName = string(line[11:])
sym = &Symbol{
Name: string(line[11:]),
Type: SymbolType(line[9]),
}
if sym.FAddr = hasAddr(line); sym.FAddr {
sym.Addr = uint64(hexUint32(line))
}
}
sym.Name, sym.VersionType, sym.Version = parseSymName(fullSymName)
item.Symbols = append(item.Symbols, sym)
}
return
}
func parseSymName(symName string) (name string, versionType VersionType, version string) {
if idx := strings.LastIndex(symName, "@"); idx != -1 {
name = symName[:idx]
version = symName[idx+1:]
if idx > 0 && symName[idx-1] == '@' {
versionType = VersionDefault
name = symName[:idx-1]
} else {
versionType = VersionSpecific
}
} else {
name = symName
versionType = VersionNone
}
return
}
func hasAddr(line []byte) bool {
c := line[0]
return c != ' ' && c != '-'