c/clang/symg: use xtool/nm to parse symbol
This commit is contained in:
@@ -17,13 +17,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -34,6 +31,7 @@ import (
|
|||||||
"github.com/goplus/llgo/chore/_xtool/llcppsymg/parse"
|
"github.com/goplus/llgo/chore/_xtool/llcppsymg/parse"
|
||||||
"github.com/goplus/llgo/chore/llcppg/types"
|
"github.com/goplus/llgo/chore/llcppg/types"
|
||||||
"github.com/goplus/llgo/cpp/llvm"
|
"github.com/goplus/llgo/cpp/llvm"
|
||||||
|
"github.com/goplus/llgo/xtool/nm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -124,21 +122,26 @@ func getStringArrayItem(obj *cjson.JSON, key string) (value []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseDylibSymbols(lib string) ([]types.CPPSymbol, error) {
|
func parseDylibSymbols(lib string) ([]types.CPPSymbol, error) {
|
||||||
dylibPath, _ := generateDylibPath(lib)
|
dylibPath, err := generateDylibPath(lib)
|
||||||
nmCmd := exec.Command("nm", "-gU", dylibPath)
|
|
||||||
nmOutput, err := nmCmd.Output() // maybe lock
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("failed to execute nm command")
|
return nil, errors.New("failed to generate dylib path")
|
||||||
}
|
}
|
||||||
|
|
||||||
symbols := parseNmOutput(nmOutput)
|
files, err := nm.New("").List(dylibPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("failed to list symbols in dylib")
|
||||||
|
}
|
||||||
|
|
||||||
for i, sym := range symbols {
|
var symbols []types.CPPSymbol
|
||||||
decodedName, err := decodeSymbolName(sym.Name)
|
|
||||||
if err != nil {
|
for _, file := range files {
|
||||||
return nil, err
|
for _, sym := range file.Symbols {
|
||||||
|
demangleName := decodeSymbolName(sym.Name)
|
||||||
|
symbols = append(symbols, types.CPPSymbol{
|
||||||
|
Symbol: sym,
|
||||||
|
DemangleName: demangleName,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
symbols[i].Name = decodedName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return symbols, nil
|
return symbols, nil
|
||||||
@@ -164,35 +167,28 @@ func generateDylibPath(lib string) (string, error) {
|
|||||||
return dylibPath, nil
|
return dylibPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNmOutput(output []byte) []types.CPPSymbol {
|
func decodeSymbolName(symbolName string) string {
|
||||||
scanner := bufio.NewScanner(bytes.NewReader(output))
|
if symbolName == "" {
|
||||||
var symbols []types.CPPSymbol
|
return ""
|
||||||
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
fields := strings.Fields(line)
|
|
||||||
if len(fields) < 3 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
symbolName := fields[2]
|
|
||||||
// Check if the symbol name starts with an underscore and remove it if present
|
|
||||||
symbolName = strings.TrimPrefix(symbolName, "_")
|
|
||||||
symbols = append(symbols, types.CPPSymbol{
|
|
||||||
Symbol: symbolName,
|
|
||||||
Type: fields[1],
|
|
||||||
Name: fields[2],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return symbols
|
demangled := llvm.ItaniumDemangle(symbolName, true)
|
||||||
}
|
if demangled == nil {
|
||||||
|
return symbolName
|
||||||
|
}
|
||||||
|
defer c.Free(unsafe.Pointer(demangled))
|
||||||
|
|
||||||
func decodeSymbolName(symbolName string) (string, error) {
|
demangleName := c.GoString(demangled)
|
||||||
llvm.ItaniumDemangle(symbolName, true)
|
if demangleName == "" {
|
||||||
demangleName := c.GoString(llvm.ItaniumDemangle(symbolName, true))
|
return symbolName
|
||||||
decodedName := strings.TrimSpace(string(demangleName))
|
}
|
||||||
decodedName = strings.ReplaceAll(decodedName, "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const", "std::string")
|
|
||||||
return decodedName, nil
|
decodedName := strings.TrimSpace(demangleName)
|
||||||
|
decodedName = strings.ReplaceAll(decodedName,
|
||||||
|
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const",
|
||||||
|
"std::string")
|
||||||
|
|
||||||
|
return decodedName
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateHeaderFilePath(cflags string, files []string) []string {
|
func generateHeaderFilePath(cflags string, files []string) []string {
|
||||||
@@ -211,11 +207,11 @@ func getCommonSymbols(dylibSymbols []types.CPPSymbol, astInfoList []types.ASTInf
|
|||||||
|
|
||||||
for _, astInfo := range astInfoList {
|
for _, astInfo := range astInfoList {
|
||||||
for _, dylibSym := range dylibSymbols {
|
for _, dylibSym := range dylibSymbols {
|
||||||
if dylibSym.Symbol == astInfo.Symbol {
|
if strings.TrimPrefix(dylibSym.Name, "_") == astInfo.Symbol {
|
||||||
cppName := generateCPPName(astInfo)
|
cppName := generateCPPName(astInfo)
|
||||||
functionNameMap[cppName]++
|
functionNameMap[cppName]++
|
||||||
symbolInfo := types.SymbolInfo{
|
symbolInfo := types.SymbolInfo{
|
||||||
Mangle: dylibSym.Symbol,
|
Mangle: strings.TrimPrefix(dylibSym.Name, "_"),
|
||||||
CPP: cppName,
|
CPP: cppName,
|
||||||
Go: generateMangle(astInfo, functionNameMap[cppName], prefix),
|
Go: generateMangle(astInfo, functionNameMap[cppName], prefix),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/goplus/llgo/c/cjson"
|
"github.com/goplus/llgo/c/cjson"
|
||||||
|
"github.com/goplus/llgo/xtool/nm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config represents a configuration for the llcppg tool.
|
// Config represents a configuration for the llcppg tool.
|
||||||
@@ -35,9 +36,8 @@ type Conf struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CPPSymbol struct {
|
type CPPSymbol struct {
|
||||||
Symbol string `json:"symbol"`
|
DemangleName string
|
||||||
Type string `json:"type"`
|
*nm.Symbol
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ASTInformation struct {
|
type ASTInformation struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user