Skip to content

Commit

Permalink
feat: support path handle on multi platform
Browse files Browse the repository at this point in the history
  • Loading branch information
Zxilly committed Jan 30, 2024
1 parent 3a282f1 commit 44a1928
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 77 deletions.
15 changes: 9 additions & 6 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: build
name: Build and tests

on:
push:
Expand All @@ -7,23 +7,26 @@ on:
branches: [ develop, master ]

jobs:

build:
runs-on: ubuntu-latest
build_and_tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true

- name: Set up Go
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: ">=1.21.0"

- name: Build
run: go build -o a

- name: Test
shell: bash
run: go test -timeout 1800s -v -race -coverprofile=coverage.txt -covermode=atomic -tags slow_test

- name: Codecov
Expand Down
7 changes: 3 additions & 4 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"sort"
"sync"
)
Expand Down Expand Up @@ -237,7 +236,7 @@ func (f *GoFile) enumPackages() error {
p, ok := packages[n.PackageName()]
if !ok {
p = &Package{
Filepath: filepath.Dir(n.BaseName()),
Filepath: "", // to be filled later by dir(PCToLine())
Functions: make([]*Function, 0),
Methods: make([]*Method, 0),
}
Expand All @@ -261,7 +260,7 @@ func (f *GoFile) enumPackages() error {

if !ok && needFilepath {
fp, _, _ := tab.PCToLine(m.Offset)
p.Filepath = filepath.Dir(fp)
p.Filepath = osAwarePathDir(fp)
}
} else {
f := &Function{
Expand All @@ -274,7 +273,7 @@ func (f *GoFile) enumPackages() error {

if !ok && needFilepath {
fp, _, _ := tab.PCToLine(f.Offset)
p.Filepath = filepath.Dir(fp)
p.Filepath = osAwarePathDir(fp)
}
}
}
Expand Down
31 changes: 18 additions & 13 deletions goroot.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package gore

import (
"bytes"
"errors"
"fmt"
"reflect"
"strings"
Expand All @@ -28,7 +29,7 @@ import (
)

func tryFromGOROOT(f *GoFile) (string, error) {
// Check for non supported architectures.
// Check for non-supported architectures.
if f.FileInfo.Arch != Arch386 && f.FileInfo.Arch != ArchAMD64 {
return "", nil
}
Expand Down Expand Up @@ -59,9 +60,9 @@ pkgLoop:
}
}

// Check if the functions was found
// Check if the functions were found
if fcn == nil {
// If we can't find the function there is nothing to do.
// If we can't find the function, there is nothing to do.
return "", ErrNoGoRootFound
}
// Get the raw hex.
Expand Down Expand Up @@ -92,13 +93,13 @@ pkgLoop:
}
arg := inst.Args[1].(x86asm.Mem)

// First assume that the address is a direct addressing.
// First, assume that the address is a direct addressing.
addr := arg.Disp
if arg.Base == x86asm.EIP || arg.Base == x86asm.RIP {
// If the addressing is based on the instruction pointer, fix the address.
addr = addr + int64(fcn.Offset) + int64(s)
} else if arg.Base == 0 && arg.Disp > 0 {
// In order to support x32 direct addressing
// To support x32 direct addressing
} else {
continue
}
Expand Down Expand Up @@ -182,7 +183,7 @@ pkgLoop:
}
addr = addr + fcn.Offset + uint64(s)
} else if arg.Base == 0 && arg.Disp > 0 {
// In order to support x32 direct addressing
// To support x32 direct addressing
} else {
continue
}
Expand All @@ -208,7 +209,7 @@ pkgLoop:
}

func tryFromTimeInit(f *GoFile) (string, error) {
// Check for non supported architectures.
// Check for non-supported architectures.
if f.FileInfo.Arch != Arch386 && f.FileInfo.Arch != ArchAMD64 {
return "", nil
}
Expand Down Expand Up @@ -239,7 +240,7 @@ pkgLoop:
}
}

// Check if the functions was found
// Check if the functions were found
if fcn == nil {
// If we can't find the function there is nothing to do.
return "", ErrNoGoRootFound
Expand Down Expand Up @@ -276,13 +277,13 @@ pkgLoop:
}
arg := inst.Args[1].(x86asm.Mem)

// First assume that the address is a direct addressing.
// First, assume that the address is a direct addressing.
addr := arg.Disp
if arg.Base == x86asm.EIP || arg.Base == x86asm.RIP {
// If the addressing is based on the instruction pointer, fix the address.
addr = addr + int64(fcn.Offset) + int64(s)
} else if arg.Base == 0 && arg.Disp > 0 {
// In order to support x32 direct addressing
// To support x32 direct addressing
} else {
continue
}
Expand Down Expand Up @@ -332,19 +333,19 @@ func findGoRootPath(f *GoFile) (string, error) {
if goroot != "" {
return goroot, nil
}
if err != nil && err != ErrNoGoRootFound {
if err != nil && !errors.Is(err, ErrNoGoRootFound) {
return "", err
}

goroot, err = tryFromTimeInit(f)
if goroot != "" {
return goroot, nil
}
if err != nil && err != ErrNoGoRootFound {
if err != nil && !errors.Is(err, ErrNoGoRootFound) {
return "", err
}

// Try determine from std lib package paths.
// Try to determine from std lib package paths.
pkg, err := f.GetSTDLib()
if err != nil {
return "", fmt.Errorf("error when getting standard library packages: %w", err)
Expand All @@ -358,6 +359,10 @@ func findGoRootPath(f *GoFile) (string, error) {
if strings.HasSuffix(v.Filepath, subpath) {
return strings.TrimSuffix(v.Filepath, subpath), nil
}
subpathWin := fmt.Sprintf("\\src\\%s", v.Name)
if strings.HasSuffix(v.Filepath, subpathWin) {
return strings.TrimSuffix(v.Filepath, subpathWin), nil
}
}

return "", ErrNoGoRootFound
Expand Down
4 changes: 3 additions & 1 deletion goroot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ func TestExtractGoRoot(t *testing.T) {
// Golden folder does not exist
t.Skip("No golden files")
}
var expectGoRoot string = "/usr/local/go"

const expectGoRoot = "/usr/local/go"

for _, test := range goldFiles {
t.Run("get goroot form "+test, func(t *testing.T) {
r := require.New(t)
Expand Down
44 changes: 25 additions & 19 deletions package.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package gore

import (
"fmt"
"path/filepath"
"runtime/debug"
"sort"
"strings"
Expand Down Expand Up @@ -50,7 +49,7 @@ func (f *GoFile) GetSourceFiles(p *Package) []*SourceFile {
getSourceFile := func(fileName string) *SourceFile {
sf, ok := tmp[fileName]
if !ok {
return &SourceFile{Name: filepath.Base(fileName)}
return &SourceFile{Name: osAwarePathBase(fileName)}
}
return sf
}
Expand Down Expand Up @@ -118,8 +117,8 @@ type PackageClassifier interface {
func NewPathPackageClassifier(mainPkgFilepath string) *PathPackageClassifier {
return &PathPackageClassifier{
mainFilepath: mainPkgFilepath, mainFolders: []string{
filepath.Dir(mainPkgFilepath),
mainPkgFilepath,
osAwarePathDir(mainPkgFilepath),
osAwarePathClean(mainPkgFilepath),
},
}
}
Expand Down Expand Up @@ -160,11 +159,11 @@ func (c *PathPackageClassifier) Classify(pkg *Package) PackageClass {
return ClassVendor
}

parentFolder := filepath.Dir(pkg.Filepath)
parentFolder := osAwarePathDir(pkg.Filepath)

if strings.HasPrefix(pkg.Filepath, c.mainFilepath+"/vendor/") ||
strings.HasPrefix(pkg.Filepath, filepath.Dir(c.mainFilepath)+"/vendor/") ||
strings.HasPrefix(pkg.Filepath, filepath.Dir(filepath.Dir(c.mainFilepath))+"/vendor/") {
strings.HasPrefix(pkg.Filepath, osAwarePathDir(c.mainFilepath)+"/vendor/") ||
strings.HasPrefix(pkg.Filepath, osAwarePathDir(osAwarePathDir(c.mainFilepath))+"/vendor/") {
return ClassVendor
}

Expand All @@ -186,14 +185,13 @@ func (c *PathPackageClassifier) Classify(pkg *Package) PackageClass {
}
}

// If the path does not contain the "vendor" in path but has the main package folder name, assume part of main.
// If the path does not contain the "vendor" in a path but has the main package folder name, assume part of main.
if !strings.Contains(pkg.Filepath, "vendor/") &&
(filepath.Base(filepath.Dir(pkg.Filepath)) == filepath.Base(c.mainFilepath)) {
(osAwarePathBase(osAwarePathDir(pkg.Filepath)) == osAwarePathBase(c.mainFilepath)) {
return ClassMain
}

// Special case for entry point package.
if pkg.Name == "" && filepath.Base(pkg.Filepath) == "runtime" {
if pkg.Name == "" && osAwarePathBase(pkg.Filepath) == "runtime" {
return ClassSTD
}

Expand All @@ -203,12 +201,12 @@ func (c *PathPackageClassifier) Classify(pkg *Package) PackageClass {
}

// Check if it's the main parent package.
if pkg.Name != "" && !strings.Contains(pkg.Name, "/") && strings.Contains(c.mainFilepath, pkg.Name) {
if pkg.Name != "" && (!strings.Contains(pkg.Name, "/") && strings.Contains(c.mainFilepath, pkg.Name)) {
return ClassMain
}

// At this point, if the main package has a file path of "command-line-arguments" and we haven't figured out
// what class it is. We assume it being part of the main package.
// what class it is. We assume it is part of the main package.
if c.mainFilepath == "command-line-arguments" {
return ClassMain
}
Expand All @@ -220,23 +218,31 @@ func (c *PathPackageClassifier) Classify(pkg *Package) PackageClass {
// Otherwise, false is retuned.
func IsStandardLibrary(pkg string) bool {
_, ok := stdPkgs[pkg]
return ok
if ok {
return true
}

// Detect regexp.(*onePassInst).regexp/syntax type packages
tmp := strings.Split(pkg, ".")[0]
if len(tmp) < len(pkg) && IsStandardLibrary(tmp) {
return true
}

return false
}

func isGeneratedPackage(pkg *Package) bool {
// Detect regexp.(*onePassInst).regexp/syntax type packages
tmp := strings.Split(pkg.Name, ".")[0]
if len(tmp) < len(pkg.Name) && IsStandardLibrary(tmp) {
if pkg.Filepath == "<autogenerated>" {
return true
}

// Special case for no package name and path of ".".
if pkg.Name == "" && pkg.Filepath == "." {
if pkg.Name == "" && pkg.Filepath == "" {
return true
}

// Some internal stuff, classify it as Generated
if pkg.Filepath == "." && (pkg.Name == "__x86" || pkg.Name == "__i686") {
if pkg.Filepath == "" && (pkg.Name == "__x86" || pkg.Name == "__i686") {
return true
}

Expand Down
Loading

0 comments on commit 44a1928

Please sign in to comment.