Merge pull request #19 from xushiwei/q

nmindex: support 32bits && multiple directories
This commit is contained in:
xushiwei
2024-04-20 10:11:55 +08:00
committed by GitHub
3 changed files with 96 additions and 16 deletions

View File

@@ -51,10 +51,6 @@ The commands are:
func makeIndex() {
env := llvm.New()
if env.Root() == "" {
fmt.Fprintln(os.Stderr, "Please set LLGO_LLVM_ROOT first.")
return
}
home, err := os.UserHomeDir()
check(err)
@@ -62,7 +58,13 @@ func makeIndex() {
os.MkdirAll(idxDir, 0755)
b := nm.NewIndexBuilder(env.Nm())
err = b.Index(env.Root()+"/lib", idxDir, func(path string) {
libDirs := []string{
usrLib(false),
usrLib(true),
stdLib("LLGO_STDROOT"),
stdLib("LLGO_USRROOT"),
}
err = b.Index(libDirs, idxDir, func(path string) {
fmt.Println("==>", path)
})
check(err)
@@ -72,6 +74,21 @@ func query() {
panic("todo")
}
func stdLib(where string) string {
dir := os.Getenv(where)
if dir != "" {
dir += "/lib"
}
return dir
}
func usrLib(local bool) string {
if local {
return "/usr/local/lib"
}
return "/usr/lib"
}
func check(err error) {
if err != nil {
panic(err)

View File

@@ -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)
}

View File

@@ -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]
}