nmindex: support 32bits && multiple directories
This commit is contained in:
@@ -51,10 +51,6 @@ The commands are:
|
|||||||
|
|
||||||
func makeIndex() {
|
func makeIndex() {
|
||||||
env := llvm.New()
|
env := llvm.New()
|
||||||
if env.Root() == "" {
|
|
||||||
fmt.Fprintln(os.Stderr, "Please set LLGO_LLVM_ROOT first.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
home, err := os.UserHomeDir()
|
home, err := os.UserHomeDir()
|
||||||
check(err)
|
check(err)
|
||||||
@@ -62,7 +58,13 @@ func makeIndex() {
|
|||||||
os.MkdirAll(idxDir, 0755)
|
os.MkdirAll(idxDir, 0755)
|
||||||
|
|
||||||
b := nm.NewIndexBuilder(env.Nm())
|
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)
|
fmt.Println("==>", path)
|
||||||
})
|
})
|
||||||
check(err)
|
check(err)
|
||||||
@@ -72,6 +74,21 @@ func query() {
|
|||||||
panic("todo")
|
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) {
|
func check(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package nm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/base64"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -32,7 +34,24 @@ func NewIndexBuilder(nm *Cmd) *IndexBuilder {
|
|||||||
return &IndexBuilder{nm}
|
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 {
|
return filepath.WalkDir(fromDir, func(path string, d os.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -44,7 +63,9 @@ func (p *IndexBuilder) Index(fromDir, toDir string, progress func(path string))
|
|||||||
switch filepath.Ext(fname) {
|
switch filepath.Ext(fname) {
|
||||||
case ".a", ".dylib", ".so", ".dll", ".lib":
|
case ".a", ".dylib", ".so", ".dll", ".lib":
|
||||||
progress(path)
|
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)
|
e := p.IndexFile(path, outFile)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
log.Println(e)
|
log.Println(e)
|
||||||
@@ -67,12 +88,17 @@ func (p *IndexBuilder) IndexFile(arFile, outFile string) (err error) {
|
|||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
for _, sym := range item.Symbols {
|
for _, sym := range item.Symbols {
|
||||||
switch sym.Type {
|
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(byte(sym.Type))
|
||||||
b.WriteByte(' ')
|
b.WriteByte(' ')
|
||||||
b.WriteString(sym.Name)
|
b.WriteString(sym.Name)
|
||||||
b.WriteByte('\n')
|
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:
|
default:
|
||||||
log.Printf("unknown symbol type %c: %s\n", sym.Type, sym.Name)
|
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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -109,23 +110,47 @@ func listOutput(data []byte) (items []*ObjectFile, err error) {
|
|||||||
err = errInvalidOutput
|
err = errInvalidOutput
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(line) < 19 {
|
if len(line) < 10 {
|
||||||
err = errInvalidOutput
|
err = errInvalidOutput
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sym := &Symbol{
|
var sym *Symbol
|
||||||
Name: string(line[19:]),
|
if is64bits(line) {
|
||||||
Type: SymbolType(line[17]),
|
sym = &Symbol{
|
||||||
}
|
Name: string(line[19:]),
|
||||||
if sym.FAddr = line[0] != ' '; sym.FAddr {
|
Type: SymbolType(line[17]),
|
||||||
sym.Addr = hexUint64(line)
|
}
|
||||||
|
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)
|
item.Symbols = append(item.Symbols, sym)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func is64bits(line []byte) bool {
|
||||||
|
if line[0] != ' ' {
|
||||||
|
return line[8] != ' '
|
||||||
|
}
|
||||||
|
return line[9] == ' '
|
||||||
|
}
|
||||||
|
|
||||||
func hexUint64(b []byte) uint64 {
|
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
|
_ = 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 |
|
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 |
|
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
|
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 {
|
func hex(b byte) uint64 {
|
||||||
return hexTable[b]
|
return hexTable[b]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user