nmindex: support 32bits && multiple directories
This commit is contained in:
@@ -18,6 +18,8 @@ package nm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -32,7 +34,24 @@ func NewIndexBuilder(nm *Cmd) *IndexBuilder {
|
||||
return &IndexBuilder{nm}
|
||||
}
|
||||
|
||||
func (p *IndexBuilder) Index(fromDir, toDir string, progress func(path string)) (err error) {
|
||||
func (p *IndexBuilder) Index(fromDir []string, toDir string, progress func(path string)) error {
|
||||
for _, dir := range fromDir {
|
||||
if dir == "" {
|
||||
continue
|
||||
}
|
||||
if e := p.IndexDir(dir, toDir, progress); e != nil {
|
||||
if !os.IsNotExist(e) {
|
||||
log.Println(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *IndexBuilder) IndexDir(fromDir, toDir string, progress func(path string)) error {
|
||||
if abs, e := filepath.Abs(fromDir); e == nil {
|
||||
fromDir = abs
|
||||
}
|
||||
return filepath.WalkDir(fromDir, func(path string, d os.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -44,7 +63,9 @@ func (p *IndexBuilder) Index(fromDir, toDir string, progress func(path string))
|
||||
switch filepath.Ext(fname) {
|
||||
case ".a", ".dylib", ".so", ".dll", ".lib":
|
||||
progress(path)
|
||||
outFile := filepath.Join(toDir, strings.TrimPrefix(fname, "lib")+".pub")
|
||||
hash := md5.Sum([]byte(path))
|
||||
hashStr := base64.RawURLEncoding.EncodeToString(hash[:])
|
||||
outFile := filepath.Join(toDir, strings.TrimPrefix(fname, "lib")+hashStr+".pub")
|
||||
e := p.IndexFile(path, outFile)
|
||||
if e != nil {
|
||||
log.Println(e)
|
||||
@@ -67,12 +88,17 @@ func (p *IndexBuilder) IndexFile(arFile, outFile string) (err error) {
|
||||
for _, item := range items {
|
||||
for _, sym := range item.Symbols {
|
||||
switch sym.Type {
|
||||
case Text, Data, BSS, Rodata, 'S':
|
||||
case Text, Data, BSS, Rodata, 'S', 'C', 'W', 'A':
|
||||
b.WriteByte(byte(sym.Type))
|
||||
b.WriteByte(' ')
|
||||
b.WriteString(sym.Name)
|
||||
b.WriteByte('\n')
|
||||
case Undefined, LocalText, LocalData, LocalBSS, LocalASym, 'I', 'i', 'a':
|
||||
case Undefined, LocalText, LocalData, LocalBSS, LocalASym, 'I', 'i', 'a', 'w':
|
||||
/*
|
||||
if sym.Type != Undefined && strings.Contains(sym.Name, "fprintf") {
|
||||
log.Printf("skip symbol type %c: %s\n", sym.Type, sym.Name)
|
||||
}
|
||||
*/
|
||||
default:
|
||||
log.Printf("unknown symbol type %c: %s\n", sym.Type, sym.Name)
|
||||
}
|
||||
|
||||
51
x/nm/nm.go
51
x/nm/nm.go
@@ -19,6 +19,7 @@ package nm
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
@@ -109,23 +110,47 @@ func listOutput(data []byte) (items []*ObjectFile, err error) {
|
||||
err = errInvalidOutput
|
||||
return
|
||||
}
|
||||
if len(line) < 19 {
|
||||
if len(line) < 10 {
|
||||
err = errInvalidOutput
|
||||
return
|
||||
}
|
||||
sym := &Symbol{
|
||||
Name: string(line[19:]),
|
||||
Type: SymbolType(line[17]),
|
||||
}
|
||||
if sym.FAddr = line[0] != ' '; sym.FAddr {
|
||||
sym.Addr = hexUint64(line)
|
||||
var sym *Symbol
|
||||
if is64bits(line) {
|
||||
sym = &Symbol{
|
||||
Name: string(line[19:]),
|
||||
Type: SymbolType(line[17]),
|
||||
}
|
||||
if sym.FAddr = line[0] != ' '; sym.FAddr {
|
||||
sym.Addr = hexUint64(line)
|
||||
}
|
||||
} else {
|
||||
sym = &Symbol{
|
||||
Name: string(line[11:]),
|
||||
Type: SymbolType(line[9]),
|
||||
}
|
||||
if sym.FAddr = line[0] != ' '; sym.FAddr {
|
||||
sym.Addr = uint64(hexUint32(line))
|
||||
}
|
||||
}
|
||||
item.Symbols = append(item.Symbols, sym)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func is64bits(line []byte) bool {
|
||||
if line[0] != ' ' {
|
||||
return line[8] != ' '
|
||||
}
|
||||
return line[9] == ' '
|
||||
}
|
||||
|
||||
func hexUint64(b []byte) uint64 {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Fprintln(os.Stderr, "-->", string(b))
|
||||
panic(e)
|
||||
}
|
||||
}()
|
||||
_ = b[15] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return hex(b[15]) | hex(b[14])<<4 | hex(b[13])<<8 | hex(b[12])<<12 |
|
||||
hex(b[11])<<16 | hex(b[10])<<20 | hex(b[9])<<24 | hex(b[8])<<28 |
|
||||
@@ -133,6 +158,18 @@ func hexUint64(b []byte) uint64 {
|
||||
hex(b[3])<<48 | hex(b[2])<<52 | hex(b[1])<<56 | hex(b[0])<<60
|
||||
}
|
||||
|
||||
func hexUint32(b []byte) uint64 {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Fprintln(os.Stderr, "-->", string(b))
|
||||
panic(e)
|
||||
}
|
||||
}()
|
||||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return hex(b[7]) | hex(b[6])<<4 | hex(b[5])<<8 | hex(b[4])<<12 |
|
||||
hex(b[3])<<16 | hex(b[2])<<20 | hex(b[1])<<24 | hex(b[0])<<28
|
||||
}
|
||||
|
||||
func hex(b byte) uint64 {
|
||||
return hexTable[b]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user