Skip to content

Commit

Permalink
xtool/nm:version
Browse files Browse the repository at this point in the history
  • Loading branch information
luoliwoshang committed Oct 15, 2024
1 parent ace3c3e commit ea6da2e
Showing 1 changed file with 40 additions and 6 deletions.
46 changes: 40 additions & 6 deletions xtool/nm/nm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 != '-'
Expand Down

0 comments on commit ea6da2e

Please sign in to comment.