xtool/nm:symbol version
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/goplus/llgo/xtool/env/llvm"
|
"github.com/goplus/llgo/xtool/env/llvm"
|
||||||
|
nmtool "github.com/goplus/llgo/xtool/nm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -45,10 +46,17 @@ func main() {
|
|||||||
fmt.Printf("\n%s:\n", item.File)
|
fmt.Printf("\n%s:\n", item.File)
|
||||||
}
|
}
|
||||||
for _, sym := range item.Symbols {
|
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 {
|
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 {
|
} else {
|
||||||
fmt.Printf("%16s %c %s\n", "", sym.Type, sym.Name)
|
fmt.Printf("%16s %c %s%s\n", "", sym.Type, sym.Name, versionInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,12 +62,26 @@ const (
|
|||||||
LocalASym = SymbolType('s') // Local symbol in an assembler source file
|
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.
|
// Symbol represents a symbol in an object file.
|
||||||
type Symbol struct {
|
type Symbol struct {
|
||||||
Name string // symbol name
|
Name string // symbol name
|
||||||
Addr uint64 // symbol address
|
Addr uint64 // symbol address
|
||||||
Type SymbolType // symbol type
|
Type SymbolType // symbol type
|
||||||
FAddr bool // address is valid
|
FAddr bool // address is valid
|
||||||
|
VersionType VersionType // version type of the symbol
|
||||||
|
Version string // version information of the symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectFile represents an object file.
|
// ObjectFile represents an object file.
|
||||||
@@ -143,28 +157,48 @@ func listOutput(data []byte) (items []*ObjectFile, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var sym *Symbol
|
var sym *Symbol
|
||||||
|
var fullSymName string
|
||||||
if is64bits(line) {
|
if is64bits(line) {
|
||||||
|
fullSymName = string(line[19:])
|
||||||
sym = &Symbol{
|
sym = &Symbol{
|
||||||
Name: string(line[19:]),
|
|
||||||
Type: SymbolType(line[17]),
|
Type: SymbolType(line[17]),
|
||||||
}
|
}
|
||||||
if sym.FAddr = hasAddr(line); sym.FAddr {
|
if sym.FAddr = hasAddr(line); sym.FAddr {
|
||||||
sym.Addr = hexUint64(line)
|
sym.Addr = hexUint64(line)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
fullSymName = string(line[11:])
|
||||||
sym = &Symbol{
|
sym = &Symbol{
|
||||||
Name: string(line[11:]),
|
|
||||||
Type: SymbolType(line[9]),
|
Type: SymbolType(line[9]),
|
||||||
}
|
}
|
||||||
if sym.FAddr = hasAddr(line); sym.FAddr {
|
if sym.FAddr = hasAddr(line); sym.FAddr {
|
||||||
sym.Addr = uint64(hexUint32(line))
|
sym.Addr = uint64(hexUint32(line))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sym.Name, sym.VersionType, sym.Version = parseSymName(fullSymName)
|
||||||
item.Symbols = append(item.Symbols, sym)
|
item.Symbols = append(item.Symbols, sym)
|
||||||
}
|
}
|
||||||
return
|
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 {
|
func hasAddr(line []byte) bool {
|
||||||
c := line[0]
|
c := line[0]
|
||||||
return c != ' ' && c != '-'
|
return c != ' ' && c != '-'
|
||||||
|
|||||||
Reference in New Issue
Block a user