pkg/proc: remove usage of gore dependency (#3664)
This commit is contained in:
parent
f32818c9e3
commit
4a72c523be
2
go.mod
2
go.mod
@ -7,7 +7,6 @@ require (
|
||||
github.com/cosiner/argv v0.1.0
|
||||
github.com/creack/pty v1.1.20
|
||||
github.com/derekparker/trie v0.0.0-20230829180723-39f4de51ef7d
|
||||
github.com/go-delve/gore v0.11.8
|
||||
github.com/go-delve/liner v1.2.3-0.20231231155935-4726ab1d7f62
|
||||
github.com/google/go-dap v0.11.0
|
||||
github.com/hashicorp/golang-lru v1.0.2
|
||||
@ -29,6 +28,7 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -13,8 +13,6 @@ github.com/derekparker/trie v0.0.0-20230829180723-39f4de51ef7d h1:hUWoLdw5kvo2xC
|
||||
github.com/derekparker/trie v0.0.0-20230829180723-39f4de51ef7d/go.mod h1:C7Es+DLenIpPc9J6IYw4jrK0h7S9bKj4DNl8+KxGEXU=
|
||||
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
|
||||
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/go-delve/gore v0.11.8 h1:gn1rkroo/RheojBjqCwzIxEVkK3OuwYtla+0GssbYmI=
|
||||
github.com/go-delve/gore v0.11.8/go.mod h1:6RBVnEUxVGkztpRY0UDUnEzS4GqETQjWrw8rhegmN4I=
|
||||
github.com/go-delve/liner v1.2.3-0.20231231155935-4726ab1d7f62 h1:IGtvsNyIuRjl04XAOFGACozgUD7A82UffYxZt4DWbvA=
|
||||
github.com/go-delve/liner v1.2.3-0.20231231155935-4726ab1d7f62/go.mod h1:biJCRbqp51wS+I92HMqn5H8/A0PAhxn2vyOT+JqhiGI=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
|
@ -33,7 +33,6 @@ import (
|
||||
"github.com/go-delve/delve/pkg/internal/gosym"
|
||||
"github.com/go-delve/delve/pkg/logflags"
|
||||
"github.com/go-delve/delve/pkg/proc/debuginfod"
|
||||
"github.com/go-delve/gore"
|
||||
"github.com/hashicorp/golang-lru/simplelru"
|
||||
)
|
||||
|
||||
@ -1458,25 +1457,30 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w
|
||||
}
|
||||
cu := &compileUnit{}
|
||||
cu.image = image
|
||||
symTable, _, err := readPcLnTableElf(elfFile, path)
|
||||
symTable, symTabAddr, err := readPcLnTableElf(elfFile, path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read debug info (%v) and could not read go symbol table (%v)", dwerr, err)
|
||||
}
|
||||
image.symTable = symTable
|
||||
gorefile, err := gore.Open(path)
|
||||
noPtrSectionData, err := elfFile.Section(".noptrdata").Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
md, err := gorefile.Moduledata()
|
||||
md, err := parseModuleData(noPtrSectionData, symTabAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prog := gosym.ProgContaining(elfFile, md.GoFuncValue())
|
||||
roDataAddr := elfFile.Section(".rodata").Addr
|
||||
goFuncVal, err := findGoFuncVal(md, roDataAddr, bi.Arch.ptrSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prog := gosym.ProgContaining(elfFile, goFuncVal)
|
||||
inlFuncs := make(map[string]*Function)
|
||||
for _, f := range image.symTable.Funcs {
|
||||
fnEntry := f.Entry + image.StaticBase
|
||||
if prog != nil {
|
||||
inlCalls, err := image.symTable.GetInlineTree(&f, md.GoFuncValue(), prog.Vaddr, prog.ReaderAt)
|
||||
inlCalls, err := image.symTable.GetInlineTree(&f, goFuncVal, prog.Vaddr, prog.ReaderAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1549,6 +1553,53 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w
|
||||
return nil
|
||||
}
|
||||
|
||||
func findGoFuncVal(moduleData []byte, roDataAddr uint64, ptrsize int) (uint64, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
err := binary.Write(buf, binary.LittleEndian, &roDataAddr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Here we search for the value of `go.func.*` by searching through the raw bytes of the
|
||||
// runtime.moduledata structure. Since we don't know the value that we are looking for,
|
||||
// we use a known value, in this case the address of the .rodata section.
|
||||
// This is because in the layout of the struct, the rodata member is right next to
|
||||
// the value we need, making the math trivial once we find that member.
|
||||
// We use `bytes.LastIndex` specifically because the `types` struct member can also
|
||||
// contain the address of the .rodata section, so this pointer can appear multiple times
|
||||
// in the raw bytes.
|
||||
// Yes, this is very ill-advised low-level hackery but it works fine until
|
||||
// https://github.com/golang/go/issues/58474#issuecomment-1785681472 happens.
|
||||
// This code path also only runs in stripped binaries, so the whole implementation is
|
||||
// best effort anyways.
|
||||
rodata := bytes.LastIndex(moduleData, buf.Bytes()[:ptrsize])
|
||||
if rodata == -1 {
|
||||
return 0, errors.New("could not find rodata struct member")
|
||||
}
|
||||
// Layout of struct members is:
|
||||
// type moduledata struct {
|
||||
// ...
|
||||
// rodata uintptr
|
||||
// gofunc uintptr
|
||||
// ...
|
||||
// }
|
||||
// So do some pointer arithmetic to get the value we need.
|
||||
gofuncval := binary.LittleEndian.Uint64(moduleData[rodata+(1*ptrsize) : rodata+(2*ptrsize)])
|
||||
return gofuncval, nil
|
||||
}
|
||||
|
||||
func parseModuleData(dataSection []byte, tableAddr uint64) ([]byte, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
err := binary.Write(buf, binary.LittleEndian, &tableAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
off := bytes.Index(dataSection, buf.Bytes()[:4])
|
||||
if off == -1 {
|
||||
return nil, errors.New("could not find moduledata")
|
||||
}
|
||||
return dataSection[off : off+0x300], nil
|
||||
}
|
||||
|
||||
// _STT_FUNC is a code object, see /usr/include/elf.h for a full definition.
|
||||
const _STT_FUNC = 2
|
||||
|
||||
@ -1866,27 +1917,32 @@ func loadBinaryInfoMacho(bi *BinaryInfo, image *Image, path string, entryPoint u
|
||||
if len(bi.Images) <= 1 {
|
||||
fmt.Fprintln(os.Stderr, "Warning: no debug info found, some functionality will be missing such as stack traces and variable evaluation.")
|
||||
}
|
||||
symTable, err := readPcLnTableMacho(exe, path)
|
||||
symTable, symTabAddr, err := readPcLnTableMacho(exe, path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read debug info (%v) and could not read go symbol table (%v)", dwerr, err)
|
||||
}
|
||||
image.symTable = symTable
|
||||
cu := &compileUnit{}
|
||||
cu.image = image
|
||||
gorefile, err := gore.Open(path)
|
||||
noPtrSectionData, err := exe.Section("__noptrdata").Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
md, err := gorefile.Moduledata()
|
||||
md, err := parseModuleData(noPtrSectionData, symTabAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
seg := gosym.SegmentContaining(exe, md.GoFuncValue())
|
||||
roDataAddr := exe.Section("__rodata").Addr
|
||||
goFuncVal, err := findGoFuncVal(md, roDataAddr, bi.Arch.ptrSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
seg := gosym.SegmentContaining(exe, goFuncVal)
|
||||
inlFuncs := make(map[string]*Function)
|
||||
for _, f := range image.symTable.Funcs {
|
||||
fnEntry := f.Entry + image.StaticBase
|
||||
if seg != nil {
|
||||
inlCalls, err := image.symTable.GetInlineTree(&f, md.GoFuncValue(), seg.Addr, seg.ReaderAt)
|
||||
inlCalls, err := image.symTable.GetInlineTree(&f, goFuncVal, seg.Addr, seg.ReaderAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -35,24 +35,24 @@ func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, uint64, error)
|
||||
return symTable, section.Addr, nil
|
||||
}
|
||||
|
||||
func readPcLnTableMacho(exe *macho.File, path string) (*gosym.Table, error) {
|
||||
func readPcLnTableMacho(exe *macho.File, path string) (*gosym.Table, uint64, error) {
|
||||
// Default section label is __gopclntab
|
||||
sectionLabel := "__gopclntab"
|
||||
|
||||
section := exe.Section(sectionLabel)
|
||||
if section == nil {
|
||||
return nil, fmt.Errorf("could not read section __gopclntab")
|
||||
return nil, 0, fmt.Errorf("could not read section __gopclntab")
|
||||
}
|
||||
tableData, err := section.Data()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("found section but could not read __gopclntab")
|
||||
return nil, 0, fmt.Errorf("found section but could not read __gopclntab")
|
||||
}
|
||||
|
||||
addr := exe.Section("__text").Addr
|
||||
lineTable := gosym.NewLineTable(tableData, addr)
|
||||
symTable, err := gosym.NewTable([]byte{}, lineTable)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create symbol table from %s ", path)
|
||||
return nil, 0, fmt.Errorf("could not create symbol table from %s ", path)
|
||||
}
|
||||
return symTable, nil
|
||||
return symTable, section.Addr, nil
|
||||
}
|
||||
|
@ -3217,6 +3217,9 @@ func TestDebugStripped2(t *testing.T) {
|
||||
if ver.IsDevel() {
|
||||
t.Skip("not supported")
|
||||
}
|
||||
if ver.Major > 0 && ver.AfterOrEqual(goversion.GoVersion{Major: 1, Minor: 22, Rev: -1}) {
|
||||
skipOn(t, "not working on linux/arm64 with Go 1.22", "linux", "arm64")
|
||||
}
|
||||
withTestProcessArgs("inlinestripped", t, "", []string{}, protest.EnableInlining|protest.LinkStrip|protest.LinkDisableDWARF, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) {
|
||||
setFunctionBreakpointAll(p, t, "fmt.Println")
|
||||
|
||||
|
@ -2089,7 +2089,6 @@ func (d *Debugger) ListDynamicLibraries() []*proc.Image {
|
||||
d.targetMutex.Lock()
|
||||
defer d.targetMutex.Unlock()
|
||||
return d.target.Selected.BinInfo().Images[1:] // skips the first image because it's the executable file
|
||||
|
||||
}
|
||||
|
||||
// ExamineMemory returns the raw memory stored at the given address.
|
||||
|
15
vendor/github.com/go-delve/gore/.gitignore
generated
vendored
15
vendor/github.com/go-delve/gore/.gitignore
generated
vendored
@ -1,15 +0,0 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
*.swp
|
||||
|
||||
.vscode/*
|
3
vendor/github.com/go-delve/gore/.gitmodules
generated
vendored
3
vendor/github.com/go-delve/gore/.gitmodules
generated
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "testdata/gold"]
|
||||
path = testdata/gold
|
||||
url = https://github.com/goretk/testdata.git
|
27
vendor/github.com/go-delve/gore/CONTRIBUTING.md
generated
vendored
27
vendor/github.com/go-delve/gore/CONTRIBUTING.md
generated
vendored
@ -1,27 +0,0 @@
|
||||
# Want to contribute?
|
||||
|
||||
We welcome tickets, pull requests, feature suggestions.
|
||||
|
||||
When developing, please try to comply to the general code style that we try to
|
||||
maintain across the project. When introducing new features or fixing
|
||||
significant bugs, please provide tests and also include some concise
|
||||
information.
|
||||
|
||||
## Test resources
|
||||
|
||||
A lot of tests in the library requires test resources. Due to the total size of
|
||||
these files, they are not included with the source code. The `testdata` folder
|
||||
contains a helper script that can be used to build them. For building the
|
||||
resources locally `docker` is used. They are also stored in a separate repo that
|
||||
can be accessed by running: `git submodule update --init --recursive`
|
||||
|
||||
Build missing resources:
|
||||
```
|
||||
./testdata/helper.sh build
|
||||
```
|
||||
|
||||
## Download the latest Go compiler release information
|
||||
|
||||
```
|
||||
go generate
|
||||
```
|
661
vendor/github.com/go-delve/gore/LICENSE
generated
vendored
661
vendor/github.com/go-delve/gore/LICENSE
generated
vendored
@ -1,661 +0,0 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
68
vendor/github.com/go-delve/gore/README.md
generated
vendored
68
vendor/github.com/go-delve/gore/README.md
generated
vendored
@ -1,68 +0,0 @@
|
||||
[](https://github.com/goretk/gore/actions/workflows/go.yml)
|
||||

|
||||
[](https://codecov.io/gh/goretk/gore)
|
||||
[](https://goreportcard.com/report/github.com/goretk/gore)
|
||||
[](https://pkg.go.dev/github.com/goretk/gore)
|
||||
# GoRE - Package gore is a library for analyzing Go binaries
|
||||
|
||||
## How to use
|
||||
|
||||
1. Use `go get` to download the library.
|
||||
2. Import it into your project.
|
||||
3. Write a new cool tool.
|
||||
|
||||
For an example use case, please checkout [redress](https://github.com/goretk/redress).
|
||||
|
||||
### Sample code
|
||||
|
||||
Extract the main package, child packages, and sibling packages:
|
||||
```go
|
||||
f, err := gore.Open(fileStr)
|
||||
pkgs, err := f.GetPackages()
|
||||
```
|
||||
|
||||
Extract all the types in the binary:
|
||||
```go
|
||||
f, err := gore.Open(fileStr)
|
||||
typs, err := f.GetTypes()
|
||||
```
|
||||
|
||||
## Update get new Go release information
|
||||
|
||||
Instead of downloading new release of the library to get detection
|
||||
for new Go releases, it is possible to do a local pull.
|
||||
|
||||
Run `go generate` and new compiler releases will be generated from
|
||||
the git tags.
|
||||
|
||||
## Functionality
|
||||
|
||||
### Go compiler
|
||||
|
||||
The library has functionality for guessing the compiler version
|
||||
used. It searches the binary for the identifiable string left
|
||||
by the compiler. It is not perfect, so functionality for assuming
|
||||
a specific version is also provided. The version strings used are
|
||||
identical to the identifiers. For example version "1.10.1" is
|
||||
represented as "go1.10.1" and version "1.10" is represented as
|
||||
"go1.10"
|
||||
|
||||
### Function recovery
|
||||
|
||||
Function information is recovered from the pclntab. Information
|
||||
that is recovered includes: function start and end location in
|
||||
the text section, source file. The library also tries to estimate
|
||||
the first and last line number in the source file for the function.
|
||||
The methods recovered includes the receiver. All functions and
|
||||
methods belong to a package. The library tries to classify the
|
||||
type of package. If it is a standard library package, 3rd-party
|
||||
package, or part of the main application. If it unable to classify
|
||||
the package, it is classified as unknown.
|
||||
|
||||
### Type recovery
|
||||
|
||||
The types in the binary are parsed from the "typelink" list. Not
|
||||
all versions of Go are supported equally. Versions 1.7 and later
|
||||
are fully supported. Versions 1.5 and 1.6 are partially supported.
|
||||
Version prior to 1.5 are not supported at all at the moment.
|
||||
|
72
vendor/github.com/go-delve/gore/buildid.go
generated
vendored
72
vendor/github.com/go-delve/gore/buildid.go
generated
vendored
@ -1,72 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
goNoteNameELF = []byte("Go\x00\x00")
|
||||
goNoteRawStart = []byte("\xff Go build ID: \"")
|
||||
goNoteRawEnd = []byte("\"\n \xff")
|
||||
)
|
||||
|
||||
func parseBuildIDFromElf(data []byte, byteOrder binary.ByteOrder) (string, error) {
|
||||
r := bytes.NewReader(data)
|
||||
var nameLen uint32
|
||||
var idLen uint32
|
||||
var tag uint32
|
||||
err := binary.Read(r, byteOrder, &nameLen)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error when reading the BuildID name length: %w", err)
|
||||
}
|
||||
err = binary.Read(r, byteOrder, &idLen)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error when reading the BuildID ID length: %w", err)
|
||||
}
|
||||
err = binary.Read(r, byteOrder, &tag)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error when reading the BuildID tag: %w", err)
|
||||
}
|
||||
|
||||
if tag != uint32(4) {
|
||||
return "", fmt.Errorf("build ID does not match expected value. 0x%x parsed", tag)
|
||||
}
|
||||
|
||||
noteName := data[12 : 12+int(nameLen)]
|
||||
if !bytes.Equal(noteName, goNoteNameELF) {
|
||||
return "", fmt.Errorf("note name not as expected")
|
||||
}
|
||||
return string(data[16 : 16+int(idLen)]), nil
|
||||
}
|
||||
|
||||
func parseBuildIDFromRaw(data []byte) (string, error) {
|
||||
idx := bytes.Index(data, goNoteRawStart)
|
||||
if idx < 0 {
|
||||
// No Build ID
|
||||
return "", nil
|
||||
}
|
||||
end := bytes.Index(data, goNoteRawEnd)
|
||||
if end < 0 {
|
||||
return "", fmt.Errorf("malformed Build ID")
|
||||
}
|
||||
return string(data[idx+len(goNoteRawStart) : end]), nil
|
||||
}
|
65
vendor/github.com/go-delve/gore/doc.go
generated
vendored
65
vendor/github.com/go-delve/gore/doc.go
generated
vendored
@ -1,65 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/*
|
||||
Package gore is a library for analyzing Go binaries.
|
||||
|
||||
Only little endian architectures are supported.
|
||||
|
||||
Go compiler
|
||||
|
||||
The library has functionality for guessing the compiler version
|
||||
used. It searches the binary for the identifiable string left
|
||||
by the compiler. It is not perfect, so functionality for assuming
|
||||
a specific version is also provided. The version strings used are
|
||||
identical to the identifiers. For example version "1.10.1" is
|
||||
represented as "go1.10.1" and version "1.10" is represented as
|
||||
"go1.10"
|
||||
|
||||
Function recovery
|
||||
|
||||
Function information is recovered from the pclntab. Information
|
||||
that is recovered includes: function start and end location in
|
||||
the text section, source file. The library also tries to estimate
|
||||
the first and last line number in the source file for the function.
|
||||
The methods recovered includes the receiver. All functions and
|
||||
methods belong to a package. The library tries to classify the
|
||||
type of package. If it is a standard library package, 3rd-party
|
||||
package, or part of the main application. If it unable to classify
|
||||
the package, it is classified as unknown.
|
||||
|
||||
Type recovery
|
||||
|
||||
The types in the binary are parsed from the "typelink" list. Not
|
||||
all versions of Go are supported equally. Versions 1.7 and later
|
||||
are fully supported. Versions 1.5 and 1.6 are partially supported.
|
||||
Version prior to 1.5 are not supported at all at the moment.
|
||||
|
||||
Example code
|
||||
|
||||
Extract the main package, child packages, and sibling packages:
|
||||
|
||||
f, err := gore.Open(fileStr)
|
||||
pkgs, err := f.GetPackages()
|
||||
|
||||
Extract all the types in the binary:
|
||||
|
||||
f, err := gore.Open(fileStr)
|
||||
typs, err := f.GetTypes()
|
||||
|
||||
*/
|
||||
package gore
|
169
vendor/github.com/go-delve/gore/elf.go
generated
vendored
169
vendor/github.com/go-delve/gore/elf.go
generated
vendored
@ -1,169 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"debug/elf"
|
||||
"debug/gosym"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func openELF(fp string) (*elfFile, error) {
|
||||
osFile, err := os.Open(fp)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error when opening the ELF file: %w", err)
|
||||
}
|
||||
|
||||
f, err := elf.NewFile(osFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error when parsing the ELF file: %w", err)
|
||||
}
|
||||
return &elfFile{file: f, osFile: osFile}, nil
|
||||
}
|
||||
|
||||
type elfFile struct {
|
||||
file *elf.File
|
||||
osFile *os.File
|
||||
}
|
||||
|
||||
func (e *elfFile) getFile() *os.File {
|
||||
return e.osFile
|
||||
}
|
||||
|
||||
func (e *elfFile) getPCLNTab() (*gosym.Table, error) {
|
||||
pclnSection := e.file.Section(".gopclntab")
|
||||
if pclnSection == nil {
|
||||
// No section found. Check if the PIE section exist instead.
|
||||
pclnSection = e.file.Section(".data.rel.ro.gopclntab")
|
||||
}
|
||||
if pclnSection == nil {
|
||||
return nil, fmt.Errorf("no gopclntab section found")
|
||||
}
|
||||
|
||||
pclndat, err := pclnSection.Data()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get the data for the pclntab: %w", err)
|
||||
}
|
||||
|
||||
pcln := gosym.NewLineTable(pclndat, e.file.Section(".text").Addr)
|
||||
return gosym.NewTable(make([]byte, 0), pcln)
|
||||
}
|
||||
|
||||
func (e *elfFile) Close() error {
|
||||
err := e.file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return e.osFile.Close()
|
||||
}
|
||||
|
||||
func (e *elfFile) getRData() ([]byte, error) {
|
||||
section := e.file.Section(".rodata")
|
||||
if section == nil {
|
||||
return nil, ErrSectionDoesNotExist
|
||||
}
|
||||
return section.Data()
|
||||
}
|
||||
|
||||
func (e *elfFile) getCodeSection() ([]byte, error) {
|
||||
section := e.file.Section(".text")
|
||||
if section == nil {
|
||||
return nil, ErrSectionDoesNotExist
|
||||
}
|
||||
return section.Data()
|
||||
}
|
||||
|
||||
func (e *elfFile) getPCLNTABData() (uint64, []byte, error) {
|
||||
start, data, err := e.getSectionData(".gopclntab")
|
||||
if err == ErrSectionDoesNotExist {
|
||||
// Try PIE location
|
||||
return e.getSectionData(".data.rel.ro.gopclntab")
|
||||
}
|
||||
return start, data, err
|
||||
}
|
||||
|
||||
func (e *elfFile) moduledataSection() string {
|
||||
return ".noptrdata"
|
||||
}
|
||||
|
||||
func (e *elfFile) getSectionDataFromOffset(off uint64) (uint64, []byte, error) {
|
||||
for _, section := range e.file.Sections {
|
||||
if section.Offset == 0 {
|
||||
// Only exist in memory
|
||||
continue
|
||||
}
|
||||
|
||||
if section.Addr <= off && off < (section.Addr+section.Size) {
|
||||
data, err := section.Data()
|
||||
return section.Addr, data, err
|
||||
}
|
||||
}
|
||||
return 0, nil, ErrSectionDoesNotExist
|
||||
}
|
||||
|
||||
func (e *elfFile) getSectionData(name string) (uint64, []byte, error) {
|
||||
section := e.file.Section(name)
|
||||
if section == nil {
|
||||
return 0, nil, ErrSectionDoesNotExist
|
||||
}
|
||||
data, err := section.Data()
|
||||
return section.Addr, data, err
|
||||
}
|
||||
|
||||
func (e *elfFile) getFileInfo() *FileInfo {
|
||||
var wordSize int
|
||||
class := e.file.FileHeader.Class
|
||||
if class == elf.ELFCLASS32 {
|
||||
wordSize = intSize32
|
||||
}
|
||||
if class == elf.ELFCLASS64 {
|
||||
wordSize = intSize64
|
||||
}
|
||||
|
||||
var arch string
|
||||
switch e.file.Machine {
|
||||
case elf.EM_386:
|
||||
arch = Arch386
|
||||
case elf.EM_MIPS:
|
||||
arch = ArchMIPS
|
||||
case elf.EM_X86_64:
|
||||
arch = ArchAMD64
|
||||
case elf.EM_ARM:
|
||||
arch = ArchARM
|
||||
}
|
||||
|
||||
return &FileInfo{
|
||||
ByteOrder: e.file.FileHeader.ByteOrder,
|
||||
OS: e.file.Machine.String(),
|
||||
WordSize: wordSize,
|
||||
Arch: arch,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *elfFile) getBuildID() (string, error) {
|
||||
_, data, err := e.getSectionData(".note.go.buildid")
|
||||
// If the note section does not exist, we just ignore the build id.
|
||||
if err == ErrSectionDoesNotExist {
|
||||
return "", nil
|
||||
}
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error when getting note section: %w", err)
|
||||
}
|
||||
return parseBuildIDFromElf(data, e.file.ByteOrder)
|
||||
}
|
38
vendor/github.com/go-delve/gore/error.go
generated
vendored
38
vendor/github.com/go-delve/gore/error.go
generated
vendored
@ -1,38 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
// ErrNotEnoughBytesRead is returned if read call returned less bytes than what is needed.
|
||||
ErrNotEnoughBytesRead = errors.New("not enough bytes read")
|
||||
// ErrUnsupportedFile is returned if the file process is unsupported.
|
||||
ErrUnsupportedFile = errors.New("unsupported file")
|
||||
// ErrSectionDoesNotExist is returned when accessing a section that does not exist.
|
||||
ErrSectionDoesNotExist = errors.New("section does not exist")
|
||||
// ErrNoGoVersionFound is returned if no goversion was found in the binary.
|
||||
ErrNoGoVersionFound = errors.New("no goversion found")
|
||||
// ErrNoPCLNTab is returned if no PCLN table can be located.
|
||||
ErrNoPCLNTab = errors.New("no pclntab located")
|
||||
// ErrInvalidGoVersion is returned if the go version set for the file is either invalid
|
||||
// or does not match a known version by the library.
|
||||
ErrInvalidGoVersion = errors.New("invalid go version")
|
||||
// ErrNoGoRootFound is returned if no goroot was found in the binary.
|
||||
ErrNoGoRootFound = errors.New("no goroot found")
|
||||
)
|
397
vendor/github.com/go-delve/gore/file.go
generated
vendored
397
vendor/github.com/go-delve/gore/file.go
generated
vendored
@ -1,397 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"debug/gosym"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
elfMagic = []byte{0x7f, 0x45, 0x4c, 0x46}
|
||||
peMagic = []byte{0x4d, 0x5a}
|
||||
maxMagicBufLen = 4
|
||||
machoMagic1 = []byte{0xfe, 0xed, 0xfa, 0xce}
|
||||
machoMagic2 = []byte{0xfe, 0xed, 0xfa, 0xcf}
|
||||
machoMagic3 = []byte{0xce, 0xfa, 0xed, 0xfe}
|
||||
machoMagic4 = []byte{0xcf, 0xfa, 0xed, 0xfe}
|
||||
)
|
||||
|
||||
// Open opens a file and returns a handler to the file.
|
||||
func Open(filePath string) (*GoFile, error) {
|
||||
f, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = f.Seek(0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := make([]byte, maxMagicBufLen)
|
||||
n, err := f.Read(buf)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n < maxMagicBufLen {
|
||||
return nil, ErrNotEnoughBytesRead
|
||||
}
|
||||
gofile := new(GoFile)
|
||||
if fileMagicMatch(buf, elfMagic) {
|
||||
elf, err := openELF(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gofile.fh = elf
|
||||
} else if fileMagicMatch(buf, peMagic) {
|
||||
pe, err := openPE(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gofile.fh = pe
|
||||
} else if fileMagicMatch(buf, machoMagic1) || fileMagicMatch(buf, machoMagic2) || fileMagicMatch(buf, machoMagic3) || fileMagicMatch(buf, machoMagic4) {
|
||||
macho, err := openMachO(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gofile.fh = macho
|
||||
} else {
|
||||
return nil, ErrUnsupportedFile
|
||||
}
|
||||
gofile.FileInfo = gofile.fh.getFileInfo()
|
||||
|
||||
// If the ID has been removed or tampered with, this will fail. If we can't
|
||||
// get a build ID, we skip it.
|
||||
buildID, err := gofile.fh.getBuildID()
|
||||
if err == nil {
|
||||
gofile.BuildID = buildID
|
||||
}
|
||||
|
||||
// Try to extract build information.
|
||||
if bi, err := gofile.extractBuildInfo(); err == nil {
|
||||
// This error is a minor failure, it just means we don't have
|
||||
// this information. So if fails we just ignores it.
|
||||
gofile.BuildInfo = bi
|
||||
if bi.Compiler != nil {
|
||||
gofile.FileInfo.goversion = bi.Compiler
|
||||
}
|
||||
}
|
||||
|
||||
return gofile, nil
|
||||
}
|
||||
|
||||
// GoFile is a structure representing a go binary file.
|
||||
type GoFile struct {
|
||||
// BuildInfo holds the data from the buildinf structure. This can be nil
|
||||
// because it's not always available.
|
||||
BuildInfo *BuildInfo
|
||||
// FileInfo holds information about the file.
|
||||
FileInfo *FileInfo
|
||||
// BuildID is the Go build ID hash extracted from the binary.
|
||||
BuildID string
|
||||
fh fileHandler
|
||||
stdPkgs []*Package
|
||||
generated []*Package
|
||||
pkgs []*Package
|
||||
vendors []*Package
|
||||
unknown []*Package
|
||||
pclntab *gosym.Table
|
||||
initPackages sync.Once
|
||||
}
|
||||
|
||||
func (f *GoFile) init() error {
|
||||
var returnVal error
|
||||
f.initPackages.Do(func() {
|
||||
tab, err := f.PCLNTab()
|
||||
if err != nil {
|
||||
returnVal = err
|
||||
return
|
||||
}
|
||||
f.pclntab = tab
|
||||
returnVal = f.enumPackages()
|
||||
})
|
||||
return returnVal
|
||||
}
|
||||
|
||||
// GetCompilerVersion returns the Go compiler version of the compiler
|
||||
// that was used to compile the binary.
|
||||
func (f *GoFile) GetCompilerVersion() (*GoVersion, error) {
|
||||
return findGoCompilerVersion(f)
|
||||
}
|
||||
|
||||
// SourceInfo returns the source code filename, starting line number
|
||||
// and ending line number for the function.
|
||||
func (f *GoFile) SourceInfo(fn *Function) (string, int, int) {
|
||||
srcFile, _, _ := f.pclntab.PCToLine(fn.Offset)
|
||||
start, end := findSourceLines(fn.Offset, fn.End, f.pclntab)
|
||||
return srcFile, start, end
|
||||
}
|
||||
|
||||
// GetGoRoot returns the Go Root path
|
||||
// that was used to compile the binary.
|
||||
func (f *GoFile) GetGoRoot() (string, error) {
|
||||
err := f.init()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return findGoRootPath(f)
|
||||
}
|
||||
|
||||
// SetGoVersion sets the assumed compiler version that was used. This
|
||||
// can be used to force a version if gore is not able to determine the
|
||||
// compiler version used. The version string must match one of the strings
|
||||
// normally extracted from the binary. For example to set the version to
|
||||
// go 1.12.0, use "go1.12". For 1.7.2, use "go1.7.2".
|
||||
// If an incorrect version string or version not known to the library,
|
||||
// ErrInvalidGoVersion is returned.
|
||||
func (f *GoFile) SetGoVersion(version string) error {
|
||||
gv := ResolveGoVersion(version)
|
||||
if gv == nil {
|
||||
return ErrInvalidGoVersion
|
||||
}
|
||||
f.FileInfo.goversion = gv
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPackages returns the go packages that has been classified as part of the main
|
||||
// project.
|
||||
func (f *GoFile) GetPackages() ([]*Package, error) {
|
||||
err := f.init()
|
||||
return f.pkgs, err
|
||||
}
|
||||
|
||||
// GetVendors returns the 3rd party packages used by the binary.
|
||||
func (f *GoFile) GetVendors() ([]*Package, error) {
|
||||
err := f.init()
|
||||
return f.vendors, err
|
||||
}
|
||||
|
||||
// GetSTDLib returns the standard library packages used by the binary.
|
||||
func (f *GoFile) GetSTDLib() ([]*Package, error) {
|
||||
err := f.init()
|
||||
return f.stdPkgs, err
|
||||
}
|
||||
|
||||
// GetGeneratedPackages returns the compiler generated packages used by the binary.
|
||||
func (f *GoFile) GetGeneratedPackages() ([]*Package, error) {
|
||||
err := f.init()
|
||||
return f.generated, err
|
||||
}
|
||||
|
||||
// GetUnknown returns unclassified packages used by the binary. This is a catch all
|
||||
// category when the classification could not be determined.
|
||||
func (f *GoFile) GetUnknown() ([]*Package, error) {
|
||||
err := f.init()
|
||||
return f.unknown, err
|
||||
}
|
||||
|
||||
func (f *GoFile) enumPackages() error {
|
||||
tab := f.pclntab
|
||||
packages := make(map[string]*Package)
|
||||
allPackages := sort.StringSlice{}
|
||||
|
||||
for _, n := range tab.Funcs {
|
||||
needFilepath := false
|
||||
|
||||
p, ok := packages[n.PackageName()]
|
||||
if !ok {
|
||||
p = &Package{
|
||||
Filepath: filepath.Dir(n.BaseName()),
|
||||
Functions: make([]*Function, 0),
|
||||
Methods: make([]*Method, 0),
|
||||
}
|
||||
packages[n.PackageName()] = p
|
||||
allPackages = append(allPackages, n.PackageName())
|
||||
needFilepath = true
|
||||
}
|
||||
|
||||
if n.ReceiverName() != "" {
|
||||
m := &Method{
|
||||
Function: &Function{
|
||||
Name: n.BaseName(),
|
||||
Offset: n.Entry,
|
||||
End: n.End,
|
||||
PackageName: n.PackageName(),
|
||||
},
|
||||
Receiver: n.ReceiverName(),
|
||||
}
|
||||
|
||||
p.Methods = append(p.Methods, m)
|
||||
|
||||
if !ok && needFilepath {
|
||||
fp, _, _ := tab.PCToLine(m.Offset)
|
||||
p.Filepath = filepath.Dir(fp)
|
||||
}
|
||||
} else {
|
||||
f := &Function{
|
||||
Name: n.BaseName(),
|
||||
Offset: n.Entry,
|
||||
End: n.End,
|
||||
PackageName: n.PackageName(),
|
||||
}
|
||||
p.Functions = append(p.Functions, f)
|
||||
|
||||
if !ok && needFilepath {
|
||||
fp, _, _ := tab.PCToLine(f.Offset)
|
||||
p.Filepath = filepath.Dir(fp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allPackages.Sort()
|
||||
|
||||
var classifier PackageClassifier
|
||||
|
||||
if f.BuildInfo != nil && f.BuildInfo.ModInfo != nil {
|
||||
classifier = NewModPackageClassifier(f.BuildInfo.ModInfo)
|
||||
} else {
|
||||
mainPkg, ok := packages["main"]
|
||||
if !ok {
|
||||
return fmt.Errorf("no main package found")
|
||||
}
|
||||
|
||||
classifier = NewPathPackageClassifier(mainPkg.Filepath)
|
||||
}
|
||||
|
||||
for n, p := range packages {
|
||||
p.Name = n
|
||||
class := classifier.Classify(p)
|
||||
switch class {
|
||||
case ClassSTD:
|
||||
f.stdPkgs = append(f.stdPkgs, p)
|
||||
case ClassVendor:
|
||||
f.vendors = append(f.vendors, p)
|
||||
case ClassMain:
|
||||
f.pkgs = append(f.pkgs, p)
|
||||
case ClassUnknown:
|
||||
f.unknown = append(f.unknown, p)
|
||||
case ClassGenerated:
|
||||
f.generated = append(f.generated, p)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close releases the file handler.
|
||||
func (f *GoFile) Close() error {
|
||||
return f.fh.Close()
|
||||
}
|
||||
|
||||
// PCLNTab returns the PCLN table.
|
||||
func (f *GoFile) PCLNTab() (*gosym.Table, error) {
|
||||
return f.fh.getPCLNTab()
|
||||
}
|
||||
|
||||
// GetTypes returns a map of all types found in the binary file.
|
||||
func (f *GoFile) GetTypes() ([]*GoType, error) {
|
||||
if f.FileInfo.goversion == nil {
|
||||
ver, err := f.GetCompilerVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.FileInfo.goversion = ver
|
||||
}
|
||||
t, err := getTypes(f.FileInfo, f.fh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = f.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sortTypes(t), nil
|
||||
}
|
||||
|
||||
// Bytes returns a slice of raw bytes with the length in the file from the address.
|
||||
func (f *GoFile) Bytes(address uint64, length uint64) ([]byte, error) {
|
||||
base, section, err := f.fh.getSectionDataFromOffset(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if address+length-base > uint64(len(section)) {
|
||||
return nil, errors.New("length out of bounds")
|
||||
}
|
||||
|
||||
return section[address-base : address+length-base], nil
|
||||
}
|
||||
|
||||
func sortTypes(types map[uint64]*GoType) []*GoType {
|
||||
sortedList := make([]*GoType, len(types))
|
||||
|
||||
i := 0
|
||||
for _, typ := range types {
|
||||
sortedList[i] = typ
|
||||
i++
|
||||
}
|
||||
sort.Slice(sortedList, func(i, j int) bool {
|
||||
if sortedList[i].PackagePath == sortedList[j].PackagePath {
|
||||
return sortedList[i].Name < sortedList[j].Name
|
||||
}
|
||||
return sortedList[i].PackagePath < sortedList[j].PackagePath
|
||||
})
|
||||
return sortedList
|
||||
}
|
||||
|
||||
type fileHandler interface {
|
||||
io.Closer
|
||||
getPCLNTab() (*gosym.Table, error)
|
||||
getRData() ([]byte, error)
|
||||
getCodeSection() ([]byte, error)
|
||||
getSectionDataFromOffset(uint64) (uint64, []byte, error)
|
||||
getSectionData(string) (uint64, []byte, error)
|
||||
getFileInfo() *FileInfo
|
||||
getPCLNTABData() (uint64, []byte, error)
|
||||
moduledataSection() string
|
||||
getBuildID() (string, error)
|
||||
getFile() *os.File
|
||||
}
|
||||
|
||||
func fileMagicMatch(buf, magic []byte) bool {
|
||||
return bytes.HasPrefix(buf, magic)
|
||||
}
|
||||
|
||||
// FileInfo holds information about the file.
|
||||
type FileInfo struct {
|
||||
// Arch is the architecture the binary is compiled for.
|
||||
Arch string
|
||||
// OS is the operating system the binary is compiled for.
|
||||
OS string
|
||||
// ByteOrder is the byte order.
|
||||
ByteOrder binary.ByteOrder
|
||||
// WordSize is the natural integer size used by the file.
|
||||
WordSize int
|
||||
goversion *GoVersion
|
||||
}
|
||||
|
||||
const (
|
||||
ArchAMD64 = "amd64"
|
||||
ArchARM = "arm"
|
||||
ArchARM64 = "arm64"
|
||||
Arch386 = "i386"
|
||||
ArchMIPS = "mips"
|
||||
)
|
142
vendor/github.com/go-delve/gore/function.go
generated
vendored
142
vendor/github.com/go-delve/gore/function.go
generated
vendored
@ -1,142 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"debug/gosym"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Function is a representation of a Go function.
|
||||
type Function struct {
|
||||
// Name is the extracted function name.
|
||||
Name string `json:"name"`
|
||||
// Offset is the starting location for the subroutine in the binary.
|
||||
Offset uint64 `json:"offset"`
|
||||
// End is the end location for the subroutine in the binary.
|
||||
End uint64 `json:"end"`
|
||||
// PackageName is the name of the Go package the function belongs to.
|
||||
PackageName string `json:"packageName"`
|
||||
}
|
||||
|
||||
// String returns a string representation of the function.
|
||||
func (f *Function) String() string {
|
||||
return f.Name
|
||||
}
|
||||
|
||||
// Method is a representation of a Go method.
|
||||
type Method struct {
|
||||
// Receiver is the name of the method receiver.
|
||||
Receiver string `json:"receiver"`
|
||||
*Function
|
||||
}
|
||||
|
||||
// String returns a string summary of the function.
|
||||
func (m *Method) String() string {
|
||||
return fmt.Sprintf("%s%s", m.Receiver, m.Name)
|
||||
}
|
||||
|
||||
// FileEntry is a representation of an entry in a source code file. This can for example be
|
||||
// a function or a method.
|
||||
type FileEntry struct {
|
||||
// Name of the function or method.
|
||||
Name string
|
||||
// Start is the source line where the code starts.
|
||||
Start int
|
||||
// End is the source line where the code ends.
|
||||
End int
|
||||
}
|
||||
|
||||
// String returns a string representation of the entry.
|
||||
func (f FileEntry) String() string {
|
||||
return fmt.Sprintf("%s Lines: %d to %d (%d)", f.Name, f.Start, f.End, f.End-f.Start)
|
||||
}
|
||||
|
||||
// SourceFile is a representation of a source code file.
|
||||
type SourceFile struct {
|
||||
// Name of the file.
|
||||
Name string
|
||||
// Prefix that should be added to each line.
|
||||
Prefix string
|
||||
// Postfix that should be added to each line.
|
||||
Postfix string
|
||||
entries []FileEntry
|
||||
}
|
||||
|
||||
// String produces a string representation of a source code file.
|
||||
// The multi-line string has this format:
|
||||
// File: simple.go
|
||||
// main Lines: 5 to 8 (3)
|
||||
// setup Lines: 9 to 11 (2)
|
||||
// The prefix and postfix string is added to each line.
|
||||
func (s *SourceFile) String() string {
|
||||
sort.Slice(s.entries, func(i, j int) bool {
|
||||
return s.entries[i].Start < s.entries[j].Start
|
||||
})
|
||||
|
||||
numlines := len(s.entries) + 1
|
||||
lines := make([]string, numlines)
|
||||
lines[0] = fmt.Sprintf("%sFile: %s%s", s.Prefix, s.Name, s.Postfix)
|
||||
|
||||
// Entry lines
|
||||
for i, e := range s.entries {
|
||||
lines[i+1] = fmt.Sprintf("\t%s%s%s", s.Prefix, e, s.Postfix)
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
// findSourceLines walks from the entry of the function to the end and looks for the
|
||||
// final source code line number. This function is pretty expensive to execute.
|
||||
func findSourceLines(entry, end uint64, tab *gosym.Table) (int, int) {
|
||||
// We don't need the Func returned since we are operating within the same function.
|
||||
file, srcStart, _ := tab.PCToLine(entry)
|
||||
|
||||
// We walk from entry to end and check the source code line number. If it's greater
|
||||
// then the current value, we set it as the new value. If the file is different, we
|
||||
// have entered an inlined function. In this case we skip it. There is a possibility
|
||||
// that we enter an inlined function that's defined in the same file. There is no way
|
||||
// for us to tell this is the case.
|
||||
srcEnd := srcStart
|
||||
|
||||
// We take a shortcut and only check every 4 bytes. This isn't perfect, but it speeds
|
||||
// up the processes.
|
||||
for i := entry; i <= end; i = i + 4 {
|
||||
f, l, _ := tab.PCToLine(i)
|
||||
|
||||
// If this line is a different file, it's an inlined function so just continue.
|
||||
if f != file {
|
||||
continue
|
||||
}
|
||||
|
||||
// If the current line is less than the starting source line, we have entered
|
||||
// an inline function defined before this function.
|
||||
if l < srcStart {
|
||||
continue
|
||||
}
|
||||
|
||||
// If the current line is greater, we assume it being closer to the end of the
|
||||
// function definition. So we take it as the current srcEnd value.
|
||||
if l > srcEnd {
|
||||
srcEnd = l
|
||||
}
|
||||
}
|
||||
|
||||
return srcStart, srcEnd
|
||||
}
|
364
vendor/github.com/go-delve/gore/goroot.go
generated
vendored
364
vendor/github.com/go-delve/gore/goroot.go
generated
vendored
@ -1,364 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
)
|
||||
|
||||
func tryFromGOROOT(f *GoFile) (string, error) {
|
||||
// Check for non supported architectures.
|
||||
if f.FileInfo.Arch != Arch386 && f.FileInfo.Arch != ArchAMD64 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
is32 := false
|
||||
if f.FileInfo.Arch == Arch386 {
|
||||
is32 = true
|
||||
}
|
||||
|
||||
// Find runtime.GOROOT function.
|
||||
var fcn *Function
|
||||
std, err := f.GetSTDLib()
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
pkgLoop:
|
||||
for _, v := range std {
|
||||
if v.Name != "runtime" {
|
||||
continue
|
||||
}
|
||||
for _, vv := range v.Functions {
|
||||
if vv.Name != "GOROOT" {
|
||||
continue
|
||||
}
|
||||
fcn = vv
|
||||
break pkgLoop
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the functions was found
|
||||
if fcn == nil {
|
||||
// If we can't find the function there is nothing to do.
|
||||
return "", ErrNoGoRootFound
|
||||
}
|
||||
// Get the raw hex.
|
||||
buf, err := f.Bytes(fcn.Offset, fcn.End-fcn.Offset)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
s := 0
|
||||
mode := f.FileInfo.WordSize * 8
|
||||
|
||||
for s < len(buf) {
|
||||
inst, err := x86asm.Decode(buf[s:], mode)
|
||||
if err != nil {
|
||||
// If we fail to decode the instruction, something is wrong so
|
||||
// bailout.
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Update next instruction location.
|
||||
s = s + inst.Len
|
||||
|
||||
// Check if it's a "mov" instruction.
|
||||
if inst.Op != x86asm.MOV {
|
||||
continue
|
||||
}
|
||||
if inst.Args[0] != x86asm.RAX && inst.Args[0] != x86asm.EAX {
|
||||
continue
|
||||
}
|
||||
arg := inst.Args[1].(x86asm.Mem)
|
||||
|
||||
// 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
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
// If the addressing is based on the stack pointer, this is not the right
|
||||
// instruction.
|
||||
if arg.Base == x86asm.ESP || arg.Base == x86asm.RSP {
|
||||
continue
|
||||
}
|
||||
|
||||
// Resolve the pointer to the string. If we get no data, this is not the
|
||||
// right instruction.
|
||||
b, _ := f.Bytes(uint64(addr), uint64(0x20))
|
||||
if b == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
r := bytes.NewReader(b)
|
||||
ptr, err := readUIntTo64(r, f.FileInfo.ByteOrder, is32)
|
||||
if err != nil {
|
||||
// Probably not the right instruction, so go to next.
|
||||
continue
|
||||
}
|
||||
l, err := readUIntTo64(r, f.FileInfo.ByteOrder, is32)
|
||||
if err != nil {
|
||||
// Probably not the right instruction, so go to next.
|
||||
continue
|
||||
}
|
||||
|
||||
bstr, _ := f.Bytes(ptr, l)
|
||||
if bstr == nil {
|
||||
continue
|
||||
}
|
||||
ver := string(bstr)
|
||||
if !utf8.ValidString(ver) {
|
||||
return "", ErrNoGoRootFound
|
||||
}
|
||||
return ver, nil
|
||||
}
|
||||
|
||||
// for go version vary from 1.5 to 1.9
|
||||
s = 0
|
||||
var insts []x86asm.Inst
|
||||
for s < len(buf) {
|
||||
inst, err := x86asm.Decode(buf[s:], mode)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
s = s + inst.Len
|
||||
insts = append(insts, inst)
|
||||
}
|
||||
var length, addr uint64
|
||||
// Look up the address from the end of the assembly instruction
|
||||
for i := len(insts) - 1; i >= 0; i-- {
|
||||
inst := insts[i]
|
||||
|
||||
if inst.Op == x86asm.MOV && length == 0 {
|
||||
switch v := inst.Args[1].(type) {
|
||||
case x86asm.Imm:
|
||||
length = uint64(v)
|
||||
continue
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (inst.Op == x86asm.LEA || inst.Op == x86asm.MOV) && addr == 0 {
|
||||
switch v := inst.Args[1].(type) {
|
||||
case x86asm.Mem:
|
||||
arg := v
|
||||
if arg.Base == x86asm.ESP || arg.Base == x86asm.RSP {
|
||||
continue
|
||||
}
|
||||
addr = uint64(arg.Disp)
|
||||
if arg.Base == x86asm.EIP || arg.Base == x86asm.RIP {
|
||||
// If the addressing is based on the instruction pointer, fix the address.
|
||||
s = 0
|
||||
for i2, inst2 := range insts {
|
||||
if i2 > i {
|
||||
break
|
||||
}
|
||||
s += inst2.Len
|
||||
}
|
||||
addr = addr + fcn.Offset + uint64(s)
|
||||
} else if arg.Base == 0 && arg.Disp > 0 {
|
||||
// In order to support x32 direct addressing
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
case x86asm.Imm:
|
||||
addr = uint64(v)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
if length > 0 && addr > 0 {
|
||||
bstr, _ := f.Bytes(addr, length)
|
||||
if bstr == nil {
|
||||
continue
|
||||
}
|
||||
ver := string(bstr)
|
||||
if !utf8.ValidString(ver) {
|
||||
return "", ErrNoGoRootFound
|
||||
}
|
||||
return ver, nil
|
||||
}
|
||||
}
|
||||
return "", ErrNoGoRootFound
|
||||
}
|
||||
|
||||
func tryFromTimeInit(f *GoFile) (string, error) {
|
||||
// Check for non supported architectures.
|
||||
if f.FileInfo.Arch != Arch386 && f.FileInfo.Arch != ArchAMD64 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
is32 := false
|
||||
if f.FileInfo.Arch == Arch386 {
|
||||
is32 = true
|
||||
}
|
||||
|
||||
// Find time.init function.
|
||||
var fcn *Function
|
||||
std, err := f.GetSTDLib()
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
pkgLoop:
|
||||
for _, v := range std {
|
||||
if v.Name != "time" {
|
||||
continue
|
||||
}
|
||||
for _, vv := range v.Functions {
|
||||
if vv.Name != "init" {
|
||||
continue
|
||||
}
|
||||
fcn = vv
|
||||
break pkgLoop
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the functions was found
|
||||
if fcn == nil {
|
||||
// If we can't find the function there is nothing to do.
|
||||
return "", ErrNoGoRootFound
|
||||
}
|
||||
// Get the raw hex.
|
||||
buf, err := f.Bytes(fcn.Offset, fcn.End-fcn.Offset)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
s := 0
|
||||
mode := f.FileInfo.WordSize * 8
|
||||
|
||||
for s < len(buf) {
|
||||
inst, err := x86asm.Decode(buf[s:], mode)
|
||||
if err != nil {
|
||||
// If we fail to decode the instruction, something is wrong so
|
||||
// bailout.
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Update next instruction location.
|
||||
s = s + inst.Len
|
||||
|
||||
// Check if it's a "mov" instruction.
|
||||
if inst.Op != x86asm.MOV {
|
||||
continue
|
||||
}
|
||||
if inst.Args[0] != x86asm.RAX && inst.Args[0] != x86asm.ECX {
|
||||
continue
|
||||
}
|
||||
kindof := reflect.TypeOf(inst.Args[1])
|
||||
if kindof.String() != "x86asm.Mem" {
|
||||
continue
|
||||
}
|
||||
arg := inst.Args[1].(x86asm.Mem)
|
||||
|
||||
// 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
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
// Resolve the pointer to the string. If we get no data, this is not the
|
||||
// right instruction.
|
||||
b, _ := f.Bytes(uint64(addr), uint64(0x20))
|
||||
if b == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
r := bytes.NewReader(b)
|
||||
ptr, err := readUIntTo64(r, f.FileInfo.ByteOrder, is32)
|
||||
if err != nil {
|
||||
// Probably not the right instruction, so go to next.
|
||||
continue
|
||||
}
|
||||
|
||||
// If the pointer is nil, it's not the right instruction
|
||||
if ptr == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
l, err := readUIntTo64(r, f.FileInfo.ByteOrder, is32)
|
||||
if err != nil {
|
||||
// Probably not the right instruction, so go to next.
|
||||
continue
|
||||
}
|
||||
|
||||
bstr, _ := f.Bytes(ptr, l)
|
||||
if bstr == nil {
|
||||
continue
|
||||
}
|
||||
ver := string(bstr)
|
||||
if !utf8.ValidString(ver) {
|
||||
return "", ErrNoGoRootFound
|
||||
}
|
||||
return ver, nil
|
||||
}
|
||||
return "", ErrNoGoRootFound
|
||||
}
|
||||
|
||||
func findGoRootPath(f *GoFile) (string, error) {
|
||||
var goroot string
|
||||
// There is no GOROOT function may be inlined (after go1.16)
|
||||
// at this time GOROOT is obtained through time_init function
|
||||
goroot, err := tryFromGOROOT(f)
|
||||
if goroot != "" {
|
||||
return goroot, nil
|
||||
}
|
||||
if err != nil && err != ErrNoGoRootFound {
|
||||
return "", err
|
||||
}
|
||||
|
||||
goroot, err = tryFromTimeInit(f)
|
||||
if goroot != "" {
|
||||
return goroot, nil
|
||||
}
|
||||
if err != nil && err != ErrNoGoRootFound {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Try determine from std lib package paths.
|
||||
pkg, err := f.GetSTDLib()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error when getting standard library packages: %w", err)
|
||||
}
|
||||
if len(pkg) == 0 {
|
||||
return "", fmt.Errorf("no standard library packages found")
|
||||
}
|
||||
|
||||
for _, v := range pkg {
|
||||
subpath := fmt.Sprintf("/src/%s", v.Name)
|
||||
if strings.HasSuffix(v.Filepath, subpath) {
|
||||
return strings.TrimSuffix(v.Filepath, subpath), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", ErrNoGoRootFound
|
||||
}
|
250
vendor/github.com/go-delve/gore/goversion.go
generated
vendored
250
vendor/github.com/go-delve/gore/goversion.go
generated
vendored
@ -1,250 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
var goVersionMatcher = regexp.MustCompile(`(go[\d+\.]*(beta|rc)?[\d*])`)
|
||||
|
||||
// GoVersion holds information about the compiler version.
|
||||
type GoVersion struct {
|
||||
// Name is a string representation of the version.
|
||||
Name string
|
||||
// SHA is a digest of the git commit for the release.
|
||||
SHA string
|
||||
// Timestamp is a string of the timestamp when the commit was created.
|
||||
Timestamp string
|
||||
}
|
||||
|
||||
// ResolveGoVersion tries to return the GoVersion for the given tag.
|
||||
// For example the tag: go1 will return a GoVersion struct representing version 1.0 of the compiler.
|
||||
// If no goversion for the given tag is found, nil is returned.
|
||||
func ResolveGoVersion(tag string) *GoVersion {
|
||||
v, ok := goversions[tag]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// GoVersionCompare compares two version strings.
|
||||
// If a < b, -1 is returned.
|
||||
// If a == b, 0 is returned.
|
||||
// If a > b, 1 is returned.
|
||||
func GoVersionCompare(a, b string) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
return semver.Compare(buildSemVerString(a), buildSemVerString(b))
|
||||
}
|
||||
|
||||
func buildSemVerString(v string) string {
|
||||
// First remove the go prefix
|
||||
tmp := strings.TrimPrefix(v, "go")
|
||||
|
||||
// If it has a pre-release, we need to add a dash and patch version of 0.
|
||||
if strings.Contains(tmp, "beta") {
|
||||
tmp = strings.ReplaceAll(tmp, "beta", ".0-beta")
|
||||
}
|
||||
if strings.Contains(tmp, "rc") {
|
||||
tmp = strings.ReplaceAll(tmp, "rc", ".0-rc")
|
||||
}
|
||||
|
||||
return "v" + tmp
|
||||
}
|
||||
|
||||
func findGoCompilerVersion(f *GoFile) (*GoVersion, error) {
|
||||
// Try to determine the version based on the schedinit function.
|
||||
if v := tryFromSchedInit(f); v != nil {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// If no version was found, search the sections for the
|
||||
// version string.
|
||||
|
||||
data, err := f.fh.getRData()
|
||||
// If read only data section does not exist, try text.
|
||||
if err == ErrSectionDoesNotExist {
|
||||
data, err = f.fh.getCodeSection()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
notfound := false
|
||||
for !notfound {
|
||||
version := matchGoVersionString(data)
|
||||
if version == "" {
|
||||
return nil, ErrNoGoVersionFound
|
||||
}
|
||||
ver := ResolveGoVersion(version)
|
||||
// Go before 1.4 does not have the version string so if we have found
|
||||
// a version string below 1.4beta1 it is a false positive.
|
||||
if ver == nil || GoVersionCompare(ver.Name, "go1.4beta1") < 0 {
|
||||
off := bytes.Index(data, []byte(version))
|
||||
// No match
|
||||
if off == -1 {
|
||||
break
|
||||
}
|
||||
data = data[off+2:]
|
||||
continue
|
||||
}
|
||||
return ver, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// tryFromSchedInit tries to identify the version of the Go compiler that compiled the code.
|
||||
// The function "schedinit" in the "runtime" package has the only reference to this string
|
||||
// used to identify the version.
|
||||
// The function returns nil if no version is found.
|
||||
func tryFromSchedInit(f *GoFile) *GoVersion {
|
||||
// Check for non supported architectures.
|
||||
if f.FileInfo.Arch != Arch386 && f.FileInfo.Arch != ArchAMD64 {
|
||||
return nil
|
||||
}
|
||||
|
||||
is32 := false
|
||||
if f.FileInfo.Arch == Arch386 {
|
||||
is32 = true
|
||||
}
|
||||
|
||||
// Find shedinit function.
|
||||
var fcn *Function
|
||||
std, err := f.GetSTDLib()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
pkgLoop:
|
||||
for _, v := range std {
|
||||
if v.Name != "runtime" {
|
||||
continue
|
||||
}
|
||||
for _, vv := range v.Functions {
|
||||
if vv.Name != "schedinit" {
|
||||
continue
|
||||
}
|
||||
fcn = vv
|
||||
break pkgLoop
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the functions was found
|
||||
if fcn == nil {
|
||||
// If we can't find the function there is nothing to do.
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the raw hex.
|
||||
buf, err := f.Bytes(fcn.Offset, fcn.End-fcn.Offset)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
Disassemble the function until the loading of the Go version is found.
|
||||
*/
|
||||
|
||||
// Counter for how many bytes has been read.
|
||||
s := 0
|
||||
mode := f.FileInfo.WordSize * 8
|
||||
|
||||
for s < len(buf) {
|
||||
inst, err := x86asm.Decode(buf[s:], mode)
|
||||
if err != nil {
|
||||
// If we fail to decode the instruction, something is wrong so
|
||||
// bailout.
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update next instruction location.
|
||||
s = s + inst.Len
|
||||
|
||||
// Check if it's a "lea" instruction.
|
||||
if inst.Op != x86asm.LEA {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check what it's loading and if it's pointing to the compiler version used.
|
||||
// First assume that the address is a direct addressing.
|
||||
arg := inst.Args[1].(x86asm.Mem)
|
||||
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)
|
||||
}
|
||||
|
||||
// If the addressing is based on the stack pointer, this is not the right
|
||||
// instruction.
|
||||
if arg.Base == x86asm.ESP || arg.Base == x86asm.RSP {
|
||||
continue
|
||||
}
|
||||
|
||||
// Resolve the pointer to the string. If we get no data, this is not the
|
||||
// right instruction.
|
||||
b, _ := f.Bytes(uint64(addr), uint64(0x20))
|
||||
if b == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
r := bytes.NewReader(b)
|
||||
ptr, err := readUIntTo64(r, f.FileInfo.ByteOrder, is32)
|
||||
if err != nil {
|
||||
// Probably not the right instruction, so go to next.
|
||||
continue
|
||||
}
|
||||
l, err := readUIntTo64(r, f.FileInfo.ByteOrder, is32)
|
||||
if err != nil {
|
||||
// Probably not the right instruction, so go to next.
|
||||
continue
|
||||
}
|
||||
|
||||
bstr, _ := f.Bytes(ptr, l)
|
||||
if bstr == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.HasPrefix(bstr, []byte("go1.")) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Likely the version string.
|
||||
ver := string(bstr)
|
||||
|
||||
gover := ResolveGoVersion(ver)
|
||||
if gover != nil {
|
||||
return gover
|
||||
}
|
||||
|
||||
// An unknown version.
|
||||
return &GoVersion{Name: ver}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func matchGoVersionString(data []byte) string {
|
||||
return string(goVersionMatcher.Find(data))
|
||||
}
|
324
vendor/github.com/go-delve/gore/goversion_gen.go
generated
vendored
324
vendor/github.com/go-delve/gore/goversion_gen.go
generated
vendored
@ -1,324 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated at
|
||||
// 2024-02-12 22:57:07.82726101 +0000 UTC
|
||||
|
||||
package gore
|
||||
|
||||
var goversions = map[string]*GoVersion{
|
||||
"go1": {Name: "go1", SHA: "6174b5e21e73714c63061e66efdbe180e1c5491d", Timestamp: "2012-03-28T12:41:59Z"},
|
||||
"go1.0.1": {Name: "go1.0.1", SHA: "2fffba7fe19690e038314d17a117d6b87979c89f", Timestamp: "2012-04-26T19:50:14Z"},
|
||||
"go1.0.2": {Name: "go1.0.2", SHA: "cb6c6570b73a1c4d19cad94570ed277f7dae55ac", Timestamp: "2012-06-14T02:50:42Z"},
|
||||
"go1.0.3": {Name: "go1.0.3", SHA: "30be9b4313622c2077539e68826194cb1028c691", Timestamp: "2012-09-21T22:10:44Z"},
|
||||
"go1.1": {Name: "go1.1", SHA: "205f850ceacfc39d1e9d76a9569416284594ce8c", Timestamp: "2013-05-13T20:03:09Z"},
|
||||
"go1.1.1": {Name: "go1.1.1", SHA: "d260448f6b6ac10efe4ae7f6dfe944e72bc2a676", Timestamp: "2013-06-13T02:49:43Z"},
|
||||
"go1.1.2": {Name: "go1.1.2", SHA: "1d6d8fca241bb611af51e265c1b5a2e9ae904702", Timestamp: "2013-08-13T05:33:06Z"},
|
||||
"go1.10": {Name: "go1.10", SHA: "bf86aec25972f3a100c3aa58a6abcbcc35bdea49", Timestamp: "2018-02-16T16:05:53Z"},
|
||||
"go1.10.1": {Name: "go1.10.1", SHA: "ac7c0ee26dda18076d5f6c151d8f920b43340ae3", Timestamp: "2018-03-29T06:09:52Z"},
|
||||
"go1.10.2": {Name: "go1.10.2", SHA: "71bdbf431b79dff61944f22c25c7e085ccfc25d5", Timestamp: "2018-04-30T19:03:55Z"},
|
||||
"go1.10.3": {Name: "go1.10.3", SHA: "fe8a0d12b14108cbe2408b417afcaab722b0727c", Timestamp: "2018-06-06T23:47:44Z"},
|
||||
"go1.10.4": {Name: "go1.10.4", SHA: "2191fce26a7fd1cd5b4975e7bd44ab44b1d9dd78", Timestamp: "2018-08-24T19:26:40Z"},
|
||||
"go1.10.5": {Name: "go1.10.5", SHA: "1ae739797ec72acbd6d90b94a2366a31566205c2", Timestamp: "2018-11-02T20:17:59Z"},
|
||||
"go1.10.6": {Name: "go1.10.6", SHA: "25ca8f49c3fc4a68daff7a23ab613e3453be5cda", Timestamp: "2018-12-13T17:16:47Z"},
|
||||
"go1.10.7": {Name: "go1.10.7", SHA: "f5ff72d62301c4e9d0a78167fab5914ca12919bd", Timestamp: "2018-12-14T23:34:23Z"},
|
||||
"go1.10.8": {Name: "go1.10.8", SHA: "b0cb374daf646454998bac7b393f3236a2ab6aca", Timestamp: "2019-01-23T19:47:24Z"},
|
||||
"go1.10beta1": {Name: "go1.10beta1", SHA: "9ce6b5c2ed5d3d5251b9a6a0c548d5fb2c8567e8", Timestamp: "2017-12-07T17:38:51Z"},
|
||||
"go1.10beta2": {Name: "go1.10beta2", SHA: "594668a5a96267a46282ce3007a584ec07adf705", Timestamp: "2018-01-11T17:44:08Z"},
|
||||
"go1.10rc1": {Name: "go1.10rc1", SHA: "5348aed83e39bd1d450d92d7f627e994c2db6ebf", Timestamp: "2018-01-25T17:24:13Z"},
|
||||
"go1.10rc2": {Name: "go1.10rc2", SHA: "20e228f2fdb44350c858de941dff4aea9f3127b8", Timestamp: "2018-02-07T16:12:58Z"},
|
||||
"go1.11": {Name: "go1.11", SHA: "41e62b8c49d21659b48a95216e3062032285250f", Timestamp: "2018-08-24T20:18:43Z"},
|
||||
"go1.11.1": {Name: "go1.11.1", SHA: "26957168c4c0cdcc7ca4f0b19d0eb19474d224ac", Timestamp: "2018-10-01T20:59:20Z"},
|
||||
"go1.11.10": {Name: "go1.11.10", SHA: "efa061d9f5d52846dfc3dda40eaf8eccfeeae8d2", Timestamp: "2019-05-06T20:50:17Z"},
|
||||
"go1.11.11": {Name: "go1.11.11", SHA: "541c49144d73f2a03374517091835fa8a43eebe2", Timestamp: "2019-06-11T18:11:11Z"},
|
||||
"go1.11.12": {Name: "go1.11.12", SHA: "4128f163d6dca1b8d703da8cf86ef679608856a0", Timestamp: "2019-07-08T19:49:55Z"},
|
||||
"go1.11.13": {Name: "go1.11.13", SHA: "b2967c0e5c5271bb4469e1f615fb85879ebd8a57", Timestamp: "2019-08-13T16:26:07Z"},
|
||||
"go1.11.2": {Name: "go1.11.2", SHA: "e8a95aeb75536496432bcace1fb2bbfa449bf0fa", Timestamp: "2018-11-02T20:17:52Z"},
|
||||
"go1.11.3": {Name: "go1.11.3", SHA: "90c896448691b5edb0ab11110f37234f63cd28ed", Timestamp: "2018-12-13T17:14:02Z"},
|
||||
"go1.11.4": {Name: "go1.11.4", SHA: "4601a4c1b1c00fbe507508f0267ec5a9445bb7e5", Timestamp: "2018-12-14T23:34:32Z"},
|
||||
"go1.11.5": {Name: "go1.11.5", SHA: "35bb62e60a7779ff82c3067903b3306ff8666471", Timestamp: "2019-01-23T19:49:15Z"},
|
||||
"go1.11.6": {Name: "go1.11.6", SHA: "e18f2ca380f52bbf8cac039ccfdf445e9047c810", Timestamp: "2019-03-14T19:57:30Z"},
|
||||
"go1.11.7": {Name: "go1.11.7", SHA: "2c5363d9c1cf51457d6d2466a63e6576e80327f8", Timestamp: "2019-04-05T19:09:03Z"},
|
||||
"go1.11.8": {Name: "go1.11.8", SHA: "f8a63418e985d972c86d3da5bf90b7e81b72b468", Timestamp: "2019-04-08T21:30:39Z"},
|
||||
"go1.11.9": {Name: "go1.11.9", SHA: "428e5f29a957b591d82e640b619b684aa25fba4e", Timestamp: "2019-04-11T23:31:23Z"},
|
||||
"go1.11beta1": {Name: "go1.11beta1", SHA: "a12c1f26e4cc602dae62ec065a237172a5b8f926", Timestamp: "2018-06-26T20:00:51Z"},
|
||||
"go1.11beta2": {Name: "go1.11beta2", SHA: "c814ac44c0571f844718f07aa52afa47e37fb1ed", Timestamp: "2018-07-19T21:30:27Z"},
|
||||
"go1.11beta3": {Name: "go1.11beta3", SHA: "1b870077c896379c066b41657d3c9062097a6943", Timestamp: "2018-08-03T17:21:10Z"},
|
||||
"go1.11rc1": {Name: "go1.11rc1", SHA: "807e7f2420c683384dc9c6db498808ba1b7aab17", Timestamp: "2018-08-13T23:43:08Z"},
|
||||
"go1.11rc2": {Name: "go1.11rc2", SHA: "02c0c32960f65d0b9c66ec840c612f5f9623dc51", Timestamp: "2018-08-22T22:17:06Z"},
|
||||
"go1.12": {Name: "go1.12", SHA: "05e77d41914d247a1e7caf37d7125ccaa5a53505", Timestamp: "2019-02-25T23:01:48Z"},
|
||||
"go1.12.1": {Name: "go1.12.1", SHA: "0380c9ad38843d523d9c9804fe300cb7edd7cd3c", Timestamp: "2019-03-14T19:18:42Z"},
|
||||
"go1.12.10": {Name: "go1.12.10", SHA: "6c15c7cce718e1e9a47f4f0ab1bd70923b04557b", Timestamp: "2019-09-25T18:48:21Z"},
|
||||
"go1.12.11": {Name: "go1.12.11", SHA: "ef74bfc859c918aeab796c2fa18f4a5dde862343", Timestamp: "2019-10-17T17:32:27Z"},
|
||||
"go1.12.12": {Name: "go1.12.12", SHA: "9e6d3ca2794c04b3f65019ee90b6e406bcfc9286", Timestamp: "2019-10-17T21:51:57Z"},
|
||||
"go1.12.13": {Name: "go1.12.13", SHA: "a8528068d581fcd110d0cb4f3c04ad77261abf6d", Timestamp: "2019-10-31T22:53:22Z"},
|
||||
"go1.12.14": {Name: "go1.12.14", SHA: "8a720dabf102975ced5664b9cf668ac4ca080245", Timestamp: "2019-12-04T21:35:28Z"},
|
||||
"go1.12.15": {Name: "go1.12.15", SHA: "694e20f4e08af7e7669c9652424d0df9b0b83f00", Timestamp: "2020-01-09T19:00:28Z"},
|
||||
"go1.12.16": {Name: "go1.12.16", SHA: "deac3221fc4cd365fb40d269dd56551e9d354356", Timestamp: "2020-01-27T22:27:19Z"},
|
||||
"go1.12.17": {Name: "go1.12.17", SHA: "46cb016190389b7e37b21f04e5343a628ca1f662", Timestamp: "2020-02-12T19:55:29Z"},
|
||||
"go1.12.2": {Name: "go1.12.2", SHA: "ac02fdec7cd16ea8d3de1fc33def9cfabec5170d", Timestamp: "2019-04-05T19:24:53Z"},
|
||||
"go1.12.3": {Name: "go1.12.3", SHA: "62ec3dd260324d243491b271d53ccdfd4a1f14e3", Timestamp: "2019-04-08T21:30:25Z"},
|
||||
"go1.12.4": {Name: "go1.12.4", SHA: "eda3401e807be8928eed48bb5fc85ffa8e62ddb4", Timestamp: "2019-04-11T23:31:30Z"},
|
||||
"go1.12.5": {Name: "go1.12.5", SHA: "3a1b4e75f8b6c1b57db73bccf7ca871bf1a97ca9", Timestamp: "2019-05-06T21:12:37Z"},
|
||||
"go1.12.6": {Name: "go1.12.6", SHA: "4ce6a8e89668b87dce67e2f55802903d6eb9110a", Timestamp: "2019-06-11T15:21:11Z"},
|
||||
"go1.12.7": {Name: "go1.12.7", SHA: "7f416b4f048677d0784e6941516c0f1e6052b2d6", Timestamp: "2019-07-08T19:50:25Z"},
|
||||
"go1.12.8": {Name: "go1.12.8", SHA: "306a74284eb261acb34ce7f70962f357906a2759", Timestamp: "2019-08-13T16:27:09Z"},
|
||||
"go1.12.9": {Name: "go1.12.9", SHA: "06472b99cdf59f00049f3cd8c9e05ba283cb2c56", Timestamp: "2019-08-15T18:44:01Z"},
|
||||
"go1.12beta1": {Name: "go1.12beta1", SHA: "e3b4b7baad555f74b6fbc0ddc00d46ed0ac03a0a", Timestamp: "2018-12-18T23:01:06Z"},
|
||||
"go1.12beta2": {Name: "go1.12beta2", SHA: "4b3f04c63b5b1a1bbc4dfd71c34341ea4e935115", Timestamp: "2019-01-10T18:15:48Z"},
|
||||
"go1.12rc1": {Name: "go1.12rc1", SHA: "1af509d46e31a14e7ff17e23b1fd84250976b405", Timestamp: "2019-02-11T20:14:50Z"},
|
||||
"go1.13": {Name: "go1.13", SHA: "cc8838d645b2b7026c1f3aaceb011775c5ca3a08", Timestamp: "2019-09-03T17:05:17Z"},
|
||||
"go1.13.1": {Name: "go1.13.1", SHA: "b17fd8e49d24eb298c53de5cd0a8923f1e0270ba", Timestamp: "2019-09-25T18:48:17Z"},
|
||||
"go1.13.10": {Name: "go1.13.10", SHA: "a57f07aac237d366630e85d080ef1ce0c34f0d09", Timestamp: "2020-04-08T19:09:06Z"},
|
||||
"go1.13.11": {Name: "go1.13.11", SHA: "237b6067c17ac3ef1e02632b77deefb5e9837cbb", Timestamp: "2020-05-14T19:18:42Z"},
|
||||
"go1.13.12": {Name: "go1.13.12", SHA: "6be4a5eb4898c7b5e7557dda061cc09ba310698b", Timestamp: "2020-06-01T19:34:58Z"},
|
||||
"go1.13.13": {Name: "go1.13.13", SHA: "1f8859c22ccdeb969b252c8139bf4b1aae5c4909", Timestamp: "2020-07-14T14:10:10Z"},
|
||||
"go1.13.14": {Name: "go1.13.14", SHA: "d3ba94164a1c404a01369fb54ddd4f5b94d91348", Timestamp: "2020-07-16T22:23:43Z"},
|
||||
"go1.13.15": {Name: "go1.13.15", SHA: "e71b61180aa19a60c23b3b7e3f6586726ebe4fd1", Timestamp: "2020-08-06T14:43:47Z"},
|
||||
"go1.13.2": {Name: "go1.13.2", SHA: "72766093e6bd092eb18df3759055625ba8436484", Timestamp: "2019-10-17T17:32:17Z"},
|
||||
"go1.13.3": {Name: "go1.13.3", SHA: "e64356a4484deb5da57396a4cd80e26667b86b79", Timestamp: "2019-10-17T21:56:53Z"},
|
||||
"go1.13.4": {Name: "go1.13.4", SHA: "3f995c3f3b43033013013e6c7ccc93a9b1411ca9", Timestamp: "2019-10-31T22:47:33Z"},
|
||||
"go1.13.5": {Name: "go1.13.5", SHA: "9341fe073e6f7742c9d61982084874560dac2014", Timestamp: "2019-12-04T21:55:02Z"},
|
||||
"go1.13.6": {Name: "go1.13.6", SHA: "14b79df428fdab83ebc813a72ab714d1e2c488d2", Timestamp: "2020-01-09T19:00:05Z"},
|
||||
"go1.13.7": {Name: "go1.13.7", SHA: "7d2473dc81c659fba3f3b83bc6e93ca5fe37a898", Timestamp: "2020-01-27T22:26:53Z"},
|
||||
"go1.13.8": {Name: "go1.13.8", SHA: "a7acf9af07bdc288129fa5756768b41f312d05f4", Timestamp: "2020-02-12T19:55:45Z"},
|
||||
"go1.13.9": {Name: "go1.13.9", SHA: "33554bc6af72f13e5eb319fd5f5aa5c9a150a60c", Timestamp: "2020-03-19T15:17:09Z"},
|
||||
"go1.13beta1": {Name: "go1.13beta1", SHA: "60f14fddfee107dedd76c0be6b422a3d8ccc841a", Timestamp: "2019-06-26T16:35:14Z"},
|
||||
"go1.13rc1": {Name: "go1.13rc1", SHA: "ed4f3f313438b8765da6c4605060529761db0797", Timestamp: "2019-08-21T19:21:42Z"},
|
||||
"go1.13rc2": {Name: "go1.13rc2", SHA: "d7b402a49a8ef5af911d7873bdbc5f61335f1d41", Timestamp: "2019-08-29T14:35:17Z"},
|
||||
"go1.14": {Name: "go1.14", SHA: "20a838ab94178c55bc4dc23ddc332fce8545a493", Timestamp: "2020-02-25T17:40:40Z"},
|
||||
"go1.14.1": {Name: "go1.14.1", SHA: "564c76a268b75f56d6f465b82fba7f6fb929fd70", Timestamp: "2020-03-19T15:17:01Z"},
|
||||
"go1.14.10": {Name: "go1.14.10", SHA: "b5a3989dac97270b89cfce250cbb42695647d5cb", Timestamp: "2020-10-14T19:10:36Z"},
|
||||
"go1.14.11": {Name: "go1.14.11", SHA: "e82710b825958f30b924fc6dba1fd0a63b517199", Timestamp: "2020-11-05T21:21:19Z"},
|
||||
"go1.14.12": {Name: "go1.14.12", SHA: "bc9c580409b61af6b29f0cbd9d45bec63dbe2ccb", Timestamp: "2020-11-12T16:47:42Z"},
|
||||
"go1.14.13": {Name: "go1.14.13", SHA: "6eed7d361d276b69a1cfdeeb7690237a6385b073", Timestamp: "2020-12-03T17:27:26Z"},
|
||||
"go1.14.14": {Name: "go1.14.14", SHA: "ccb4f250bd7e382e50824c36ec5a3e1a57dcf11a", Timestamp: "2021-01-19T19:47:38Z"},
|
||||
"go1.14.15": {Name: "go1.14.15", SHA: "5cf057ddedfbb149b71c85ec86050431dd6b2d9d", Timestamp: "2021-02-04T20:43:04Z"},
|
||||
"go1.14.2": {Name: "go1.14.2", SHA: "96745b980cfde139e8611772e2bc0c59a8e6cdf7", Timestamp: "2020-04-08T19:09:10Z"},
|
||||
"go1.14.3": {Name: "go1.14.3", SHA: "f296b7a6f045325a230f77e9bda1470b1270f817", Timestamp: "2020-05-14T19:18:34Z"},
|
||||
"go1.14.4": {Name: "go1.14.4", SHA: "83b181c68bf332ac7948f145f33d128377a09c42", Timestamp: "2020-06-01T19:34:54Z"},
|
||||
"go1.14.5": {Name: "go1.14.5", SHA: "36fcde1676a0d3863cb5f295eed6938cd782fcbb", Timestamp: "2020-07-14T14:10:30Z"},
|
||||
"go1.14.6": {Name: "go1.14.6", SHA: "edfd6f28486017dcb136cd3f3ec252706d4b326e", Timestamp: "2020-07-16T22:23:28Z"},
|
||||
"go1.14.7": {Name: "go1.14.7", SHA: "d571a77846dfee8efd076223a882915cd6cb52f4", Timestamp: "2020-08-06T14:43:51Z"},
|
||||
"go1.14.8": {Name: "go1.14.8", SHA: "c187a3d47c41d54bd570905caad128ba947e3d03", Timestamp: "2020-09-01T14:08:43Z"},
|
||||
"go1.14.9": {Name: "go1.14.9", SHA: "26a85c3634b8b5dc9cf8adb30664dac0ddc6acf0", Timestamp: "2020-09-09T16:38:16Z"},
|
||||
"go1.14beta1": {Name: "go1.14beta1", SHA: "a5bfd9da1d1b24f326399b6b75558ded14514f23", Timestamp: "2019-12-17T14:59:30Z"},
|
||||
"go1.14rc1": {Name: "go1.14rc1", SHA: "a068054af141c01df5a4519844f4b77273605f4e", Timestamp: "2020-02-05T15:43:27Z"},
|
||||
"go1.15": {Name: "go1.15", SHA: "0fdc3801bfd43d6f55e4ea5bf095e1ea55430339", Timestamp: "2020-08-11T19:01:57Z"},
|
||||
"go1.15.1": {Name: "go1.15.1", SHA: "01af46f7cc419da19f8a6a444da8f6022c016803", Timestamp: "2020-09-01T14:08:32Z"},
|
||||
"go1.15.10": {Name: "go1.15.10", SHA: "dcffdac515a1d409bcb61783d57ddb137b4741b9", Timestamp: "2021-03-11T17:08:16Z"},
|
||||
"go1.15.11": {Name: "go1.15.11", SHA: "8c163e85267d146274f68854fe02b4a495586584", Timestamp: "2021-04-01T17:26:12Z"},
|
||||
"go1.15.12": {Name: "go1.15.12", SHA: "07d8cba9e15f5c5a3b0462a9215dbeac0cebf027", Timestamp: "2021-05-06T14:59:58Z"},
|
||||
"go1.15.13": {Name: "go1.15.13", SHA: "ab7f8297f9734b24a43a942930258cda411f16a3", Timestamp: "2021-06-03T17:14:37Z"},
|
||||
"go1.15.14": {Name: "go1.15.14", SHA: "c6d89dbf9954b101589e2db8e170b84167782109", Timestamp: "2021-07-12T19:44:54Z"},
|
||||
"go1.15.15": {Name: "go1.15.15", SHA: "acbe242f8a2cae8ef4749806291a37d23089b572", Timestamp: "2021-08-04T20:44:05Z"},
|
||||
"go1.15.2": {Name: "go1.15.2", SHA: "9706f510a5e2754595d716bd64be8375997311fb", Timestamp: "2020-09-09T16:38:12Z"},
|
||||
"go1.15.3": {Name: "go1.15.3", SHA: "1984ee00048b63eacd2155cd6d74a2d13e998272", Timestamp: "2020-10-14T19:10:41Z"},
|
||||
"go1.15.4": {Name: "go1.15.4", SHA: "0e953add9656c32a788e06438cd7b533e968b7f8", Timestamp: "2020-11-05T21:21:32Z"},
|
||||
"go1.15.5": {Name: "go1.15.5", SHA: "c53315d6cf1b4bfea6ff356b4a1524778c683bb9", Timestamp: "2020-11-12T16:39:58Z"},
|
||||
"go1.15.6": {Name: "go1.15.6", SHA: "9b955d2d3fcff6a5bc8bce7bafdc4c634a28e95b", Timestamp: "2020-12-03T17:27:17Z"},
|
||||
"go1.15.7": {Name: "go1.15.7", SHA: "2117ea9737bc9cb2e30cb087b76a283f68768819", Timestamp: "2021-01-19T19:47:12Z"},
|
||||
"go1.15.8": {Name: "go1.15.8", SHA: "fa6752a5370735b8c2404d6de5191f2eea67130f", Timestamp: "2021-02-04T20:42:57Z"},
|
||||
"go1.15.9": {Name: "go1.15.9", SHA: "13722418773b6a081816e8cc48131306565db1bd", Timestamp: "2021-03-10T14:24:59Z"},
|
||||
"go1.15beta1": {Name: "go1.15beta1", SHA: "e92be18fd8b525b642ca25bdb3e2056b35d9d73c", Timestamp: "2020-06-10T14:56:01Z"},
|
||||
"go1.15rc1": {Name: "go1.15rc1", SHA: "3e8f6b0791a670e52d25d76813d669daa68acfb4", Timestamp: "2020-07-24T16:28:26Z"},
|
||||
"go1.15rc2": {Name: "go1.15rc2", SHA: "c4f8cb43caf0bcd0c730d7d04a3fce129393cecc", Timestamp: "2020-08-07T14:56:02Z"},
|
||||
"go1.16": {Name: "go1.16", SHA: "f21be2fdc6f1becdbed1592ea0b245cdeedc5ac8", Timestamp: "2021-02-16T18:08:40Z"},
|
||||
"go1.16.1": {Name: "go1.16.1", SHA: "e9e0473681e581040b4adcd64b53967e1572fe8d", Timestamp: "2021-03-10T14:25:03Z"},
|
||||
"go1.16.10": {Name: "go1.16.10", SHA: "23991f50b34f8707bcfc7761321bb3b0e9dba10e", Timestamp: "2021-11-04T13:55:28Z"},
|
||||
"go1.16.11": {Name: "go1.16.11", SHA: "8faefcbfce6d2b2875ab74d81bb4e94b2e3adaf5", Timestamp: "2021-12-02T20:00:54Z"},
|
||||
"go1.16.12": {Name: "go1.16.12", SHA: "f1f3923d2e3a0952c698d2901fc052046fa4af3d", Timestamp: "2021-12-09T13:44:57Z"},
|
||||
"go1.16.13": {Name: "go1.16.13", SHA: "378766af9ed0f2e28d67c2b50e73db7573656669", Timestamp: "2022-01-06T19:06:36Z"},
|
||||
"go1.16.14": {Name: "go1.16.14", SHA: "0a6cf8706fdd0fe1bd26e4d1ecbcd41650bf5e6c", Timestamp: "2022-02-09T16:29:28Z"},
|
||||
"go1.16.15": {Name: "go1.16.15", SHA: "7de0c90a1771146bcba5663fb257c52acffe6161", Timestamp: "2022-03-03T16:55:37Z"},
|
||||
"go1.16.2": {Name: "go1.16.2", SHA: "3979fb9af9ccfc0b7ccb613dcf256b18c2c295f0", Timestamp: "2021-03-11T17:08:05Z"},
|
||||
"go1.16.3": {Name: "go1.16.3", SHA: "9baddd3f21230c55f0ad2a10f5f20579dcf0a0bb", Timestamp: "2021-04-01T17:26:20Z"},
|
||||
"go1.16.4": {Name: "go1.16.4", SHA: "04cd717a269d94d3b3459a3aaf43bc71e3112b7a", Timestamp: "2021-05-06T15:00:00Z"},
|
||||
"go1.16.5": {Name: "go1.16.5", SHA: "7677616a263e8ded606cc8297cb67ddc667a876e", Timestamp: "2021-06-03T17:14:44Z"},
|
||||
"go1.16.6": {Name: "go1.16.6", SHA: "bc51e930274a5d5835ac8797978afc0864c9e30c", Timestamp: "2021-07-12T19:45:05Z"},
|
||||
"go1.16.7": {Name: "go1.16.7", SHA: "fa6aa872225f8d33a90d936e7a81b64d2cea68e1", Timestamp: "2021-08-04T20:44:12Z"},
|
||||
"go1.16.8": {Name: "go1.16.8", SHA: "170a72e58bd128b421f4b3974fe2a37fd035efdf", Timestamp: "2021-09-09T15:27:16Z"},
|
||||
"go1.16.9": {Name: "go1.16.9", SHA: "c580180744e60d6c84fc0b59d634fcff01290780", Timestamp: "2021-10-07T19:49:45Z"},
|
||||
"go1.16beta1": {Name: "go1.16beta1", SHA: "2ff33f5e443165e55a080f3a649e4c070c4096d1", Timestamp: "2020-12-17T16:03:19Z"},
|
||||
"go1.16rc1": {Name: "go1.16rc1", SHA: "3e06467282c6d5678a6273747658c04314e013ef", Timestamp: "2021-01-27T22:19:13Z"},
|
||||
"go1.17": {Name: "go1.17", SHA: "ec5170397c724a8ae440b2bc529f857c86f0e6b1", Timestamp: "2021-08-16T16:23:06Z"},
|
||||
"go1.17.1": {Name: "go1.17.1", SHA: "21a4e67ad58e3c4a7c5254f60cda5be5c3c450ff", Timestamp: "2021-09-09T15:27:21Z"},
|
||||
"go1.17.10": {Name: "go1.17.10", SHA: "085c61ae517110168841be0afeb8f883d66fe95a", Timestamp: "2022-05-10T16:14:36Z"},
|
||||
"go1.17.11": {Name: "go1.17.11", SHA: "26cdea3acca29db94541236f0037a20aa22ce2d7", Timestamp: "2022-06-01T15:18:41Z"},
|
||||
"go1.17.12": {Name: "go1.17.12", SHA: "1ed3c127daceaffb9aadc806ba60f0b51b47421b", Timestamp: "2022-07-12T20:15:34Z"},
|
||||
"go1.17.13": {Name: "go1.17.13", SHA: "15da892a4950a4caac987ee72c632436329f62d5", Timestamp: "2022-08-01T15:12:52Z"},
|
||||
"go1.17.2": {Name: "go1.17.2", SHA: "2ac3bdf378ae408ad8c993084c1c6f7d05b7dff8", Timestamp: "2021-10-07T18:11:41Z"},
|
||||
"go1.17.3": {Name: "go1.17.3", SHA: "f58c78a5771570667b26e8c74faa017bd4c2c448", Timestamp: "2021-11-04T13:55:24Z"},
|
||||
"go1.17.4": {Name: "go1.17.4", SHA: "0f2d0d0694c8680909252ca45dbffbcaff8e430a", Timestamp: "2021-12-02T20:02:34Z"},
|
||||
"go1.17.5": {Name: "go1.17.5", SHA: "de690c2ff8e323c7ce9e274f986dc6f824b35405", Timestamp: "2021-12-09T13:44:55Z"},
|
||||
"go1.17.6": {Name: "go1.17.6", SHA: "9de1ac6ac2cad3871760d0aa288f5ca713afd0a6", Timestamp: "2022-01-06T19:06:43Z"},
|
||||
"go1.17.7": {Name: "go1.17.7", SHA: "6a70ee2873b2367e2a0d6e7d7e167c072b99daf0", Timestamp: "2022-02-09T18:09:24Z"},
|
||||
"go1.17.8": {Name: "go1.17.8", SHA: "7dd10d4ce20e64d96a10cb67794851a58d96a2aa", Timestamp: "2022-03-03T16:55:45Z"},
|
||||
"go1.17.9": {Name: "go1.17.9", SHA: "346b18ee9d15410ab08dd583787c64dbed0666d2", Timestamp: "2022-04-12T15:40:31Z"},
|
||||
"go1.17beta1": {Name: "go1.17beta1", SHA: "dc00dc6c6bf3b5554e37f60799aec092276ff807", Timestamp: "2021-06-10T12:41:37Z"},
|
||||
"go1.17rc1": {Name: "go1.17rc1", SHA: "ddfd72f7d10a40a87513a320dae8c52b6dfdb778", Timestamp: "2021-07-13T17:12:38Z"},
|
||||
"go1.17rc2": {Name: "go1.17rc2", SHA: "72ab3ff68b1ec894fe5599ec82b8849f3baa9d94", Timestamp: "2021-08-02T17:57:22Z"},
|
||||
"go1.18": {Name: "go1.18", SHA: "4aa1efed4853ea067d665a952eee77c52faac774", Timestamp: "2022-03-15T14:06:18Z"},
|
||||
"go1.18.1": {Name: "go1.18.1", SHA: "0b0d2fe66d2348fa694a925595807859bf08a391", Timestamp: "2022-04-12T15:40:19Z"},
|
||||
"go1.18.10": {Name: "go1.18.10", SHA: "581603cb7d02019bbf4ff508014038f3120a3dcb", Timestamp: "2023-01-10T18:17:59Z"},
|
||||
"go1.18.2": {Name: "go1.18.2", SHA: "8ed0e51b5e5cc50985444f39dc56c55e4fa3bcf9", Timestamp: "2022-05-10T16:47:15Z"},
|
||||
"go1.18.3": {Name: "go1.18.3", SHA: "4068be56ce7721a3d75606ea986d11e9ca27077a", Timestamp: "2022-06-01T16:38:24Z"},
|
||||
"go1.18.4": {Name: "go1.18.4", SHA: "88a06f40dfcdc4d37346be169f2b1b9070f38bb3", Timestamp: "2022-07-12T19:56:08Z"},
|
||||
"go1.18.5": {Name: "go1.18.5", SHA: "be59153dd8e67d83428e18a44dd29df3059c21fe", Timestamp: "2022-08-01T15:12:43Z"},
|
||||
"go1.18.6": {Name: "go1.18.6", SHA: "170d78d9baa82d1b64682c5d1f15e5f386f18f3e", Timestamp: "2022-09-06T16:17:30Z"},
|
||||
"go1.18.7": {Name: "go1.18.7", SHA: "947091d31ccda14b0a362adff37b6e037f0f59f3", Timestamp: "2022-10-04T17:43:09Z"},
|
||||
"go1.18.8": {Name: "go1.18.8", SHA: "156bf3dd36a9264f721dc98749c8899c559cca43", Timestamp: "2022-11-01T16:45:18Z"},
|
||||
"go1.18.9": {Name: "go1.18.9", SHA: "0d8a92bdfd3d6d1b24f47e05f9be46645aec94f0", Timestamp: "2022-12-06T19:30:49Z"},
|
||||
"go1.18beta1": {Name: "go1.18beta1", SHA: "becaeea1199b875bc24800fa88f2f4fea119bf78", Timestamp: "2021-12-14T17:43:51Z"},
|
||||
"go1.18beta2": {Name: "go1.18beta2", SHA: "41f485b9a7d8fd647c415be1d11b612063dff21c", Timestamp: "2022-01-31T13:43:52Z"},
|
||||
"go1.18rc1": {Name: "go1.18rc1", SHA: "cb5a598d7f2ebd276686403d141a97c026d33458", Timestamp: "2022-02-16T22:23:24Z"},
|
||||
"go1.19": {Name: "go1.19", SHA: "43456202a1e55da55666fac9d56ace7654a65b64", Timestamp: "2022-08-02T16:54:47Z"},
|
||||
"go1.19.1": {Name: "go1.19.1", SHA: "4a4127bccc826ebb6079af3252bc6bfeaec187c4", Timestamp: "2022-09-06T16:17:26Z"},
|
||||
"go1.19.10": {Name: "go1.19.10", SHA: "7fe60b5df764f5a16a2c40e4412b5ed60f709192", Timestamp: "2023-06-06T17:46:04Z"},
|
||||
"go1.19.11": {Name: "go1.19.11", SHA: "e58941fc25771784319ebd0178e566ecf7d3d8c1", Timestamp: "2023-07-11T16:38:32Z"},
|
||||
"go1.19.12": {Name: "go1.19.12", SHA: "0ae54ddd37302bdd2a8c775135bf5f076a18eeb3", Timestamp: "2023-08-01T20:11:51Z"},
|
||||
"go1.19.13": {Name: "go1.19.13", SHA: "619b8fd7d2c94af12933f409e962b99aa9263555", Timestamp: "2023-09-06T15:37:56Z"},
|
||||
"go1.19.2": {Name: "go1.19.2", SHA: "895664482c0ebe5cec4a6935615a1e9610bbf1e3", Timestamp: "2022-10-04T17:43:19Z"},
|
||||
"go1.19.3": {Name: "go1.19.3", SHA: "5d5ed57b134b7a02259ff070864f753c9e601a18", Timestamp: "2022-11-01T16:45:23Z"},
|
||||
"go1.19.4": {Name: "go1.19.4", SHA: "dc04f3ba1f25313bc9c97e728620206c235db9ee", Timestamp: "2022-12-06T19:30:53Z"},
|
||||
"go1.19.5": {Name: "go1.19.5", SHA: "1e9ff255a130200fcc4ec5e911d28181fce947d5", Timestamp: "2023-01-10T18:15:26Z"},
|
||||
"go1.19.6": {Name: "go1.19.6", SHA: "8656c03fee94ce9cdc4da120b831c2fb9fd68d9d", Timestamp: "2023-02-14T18:09:51Z"},
|
||||
"go1.19.7": {Name: "go1.19.7", SHA: "7bd22aafe41be40e2174335a3dc55431ca9548ec", Timestamp: "2023-03-07T16:49:31Z"},
|
||||
"go1.19.8": {Name: "go1.19.8", SHA: "ca305e101d89969b5cc6a812b1f12038b769aaa2", Timestamp: "2023-04-04T17:30:16Z"},
|
||||
"go1.19.9": {Name: "go1.19.9", SHA: "484330d038d060c6e4db3dc8e6ea2b811b2a44d8", Timestamp: "2023-05-02T17:21:05Z"},
|
||||
"go1.19beta1": {Name: "go1.19beta1", SHA: "2cfbef438049fd4c3f73d1562773ad1f93900897", Timestamp: "2022-06-09T19:31:37Z"},
|
||||
"go1.19rc1": {Name: "go1.19rc1", SHA: "bac4eb53d64ee402af1d52ac18fb9f0ea76c74e2", Timestamp: "2022-07-06T21:33:10Z"},
|
||||
"go1.19rc2": {Name: "go1.19rc2", SHA: "ad672e7ce101cc52e38bae3d7484e4660a20d575", Timestamp: "2022-07-12T22:09:01Z"},
|
||||
"go1.1rc2": {Name: "go1.1rc2", SHA: "1c5438aae896edcd1e9f9618f4776517f08053b3", Timestamp: "2013-05-07T00:33:44Z"},
|
||||
"go1.1rc3": {Name: "go1.1rc3", SHA: "46a6097aa7943a490e9bd2e04274845d0e5e200f", Timestamp: "2013-05-08T23:04:56Z"},
|
||||
"go1.2": {Name: "go1.2", SHA: "402d3590b54e4a0df9fb51ed14b2999e85ce0b76", Timestamp: "2013-11-28T21:32:31Z"},
|
||||
"go1.2.1": {Name: "go1.2.1", SHA: "9c9802fad57c1bcb72ea98c5c55ea2652efc5772", Timestamp: "2014-03-03T00:53:08Z"},
|
||||
"go1.2.2": {Name: "go1.2.2", SHA: "43d00b0942c1c6f43993ac71e1eea48e62e22b8d", Timestamp: "2014-05-05T17:43:37Z"},
|
||||
"go1.20": {Name: "go1.20", SHA: "de4748c47c67392a57f250714509f590f68ad395", Timestamp: "2023-02-01T19:03:46Z"},
|
||||
"go1.20.1": {Name: "go1.20.1", SHA: "202a1a57064127c3f19d96df57b9f9586145e21c", Timestamp: "2023-02-14T18:12:19Z"},
|
||||
"go1.20.10": {Name: "go1.20.10", SHA: "8042fd87f37a725e34407994c9a11aaf95f5af45", Timestamp: "2023-10-10T16:26:21Z"},
|
||||
"go1.20.11": {Name: "go1.20.11", SHA: "1d0d4b149ce71083ec474d0491851ab2d2dc695e", Timestamp: "2023-11-07T17:55:05Z"},
|
||||
"go1.20.12": {Name: "go1.20.12", SHA: "97c8ff8d53759e7a82b1862403df1694f2b6e073", Timestamp: "2023-12-05T18:12:58Z"},
|
||||
"go1.20.13": {Name: "go1.20.13", SHA: "a95136a88cb8a51ede3ec2cdca4cfa3962dcfacd", Timestamp: "2024-01-09T18:15:45Z"},
|
||||
"go1.20.14": {Name: "go1.20.14", SHA: "90a870f1dc49bfcc6ffe95f80fbaf21875198e7a", Timestamp: "2024-02-06T18:22:28Z"},
|
||||
"go1.20.2": {Name: "go1.20.2", SHA: "aee9a19c559da6fd258a8609556d89f6fad2a6d8", Timestamp: "2023-03-07T16:47:18Z"},
|
||||
"go1.20.3": {Name: "go1.20.3", SHA: "7c47a6b15782b13ecb76fd3c6c18e5f1edc34733", Timestamp: "2023-04-04T17:30:09Z"},
|
||||
"go1.20.4": {Name: "go1.20.4", SHA: "324c3ace2d2e4e30949baa23b4c9aac8a4123317", Timestamp: "2023-05-02T17:21:02Z"},
|
||||
"go1.20.5": {Name: "go1.20.5", SHA: "e827d41c0a2ea392c117a790cdfed0022e419424", Timestamp: "2023-06-06T17:39:34Z"},
|
||||
"go1.20.6": {Name: "go1.20.6", SHA: "2c358ffe9762ba08c8db0196942395f97775e31b", Timestamp: "2023-07-11T15:58:20Z"},
|
||||
"go1.20.7": {Name: "go1.20.7", SHA: "adb775e309dea43157e931835e920ac9e7769abe", Timestamp: "2023-08-01T19:34:15Z"},
|
||||
"go1.20.8": {Name: "go1.20.8", SHA: "d5b851804329aa547dafa278a0c35dd62298d651", Timestamp: "2023-09-06T15:31:47Z"},
|
||||
"go1.20.9": {Name: "go1.20.9", SHA: "68f9a6e2addc828246992e66e79c6a51a32d1d71", Timestamp: "2023-10-05T19:28:06Z"},
|
||||
"go1.20rc1": {Name: "go1.20rc1", SHA: "9f0234214473dfb785a5ad84a8fc62a6a395cbc3", Timestamp: "2022-12-07T22:00:46Z"},
|
||||
"go1.20rc2": {Name: "go1.20rc2", SHA: "32593a91927dbb891e00a5a94abb04105f6a8aa8", Timestamp: "2023-01-04T16:02:35Z"},
|
||||
"go1.20rc3": {Name: "go1.20rc3", SHA: "b3160e8bcedb25c5266e047ada01b6f462521401", Timestamp: "2023-01-12T17:16:08Z"},
|
||||
"go1.21.0": {Name: "go1.21.0", SHA: "c19c4c566c63818dfd059b352e52c4710eecf14d", Timestamp: "2023-08-08T15:00:52Z"},
|
||||
"go1.21.1": {Name: "go1.21.1", SHA: "2c1e5b05fe39fc5e6c730dd60e82946b8e67c6ba", Timestamp: "2023-09-06T15:31:51Z"},
|
||||
"go1.21.2": {Name: "go1.21.2", SHA: "26b5783b72376acd0386f78295e678b9a6bff30e", Timestamp: "2023-10-05T19:06:58Z"},
|
||||
"go1.21.3": {Name: "go1.21.3", SHA: "883f062fc0a097bf561030ad453fd3e300896975", Timestamp: "2023-10-10T16:31:03Z"},
|
||||
"go1.21.4": {Name: "go1.21.4", SHA: "ed817f1c4055a559a94afffecbb91c78e4f39942", Timestamp: "2023-11-07T17:38:04Z"},
|
||||
"go1.21.5": {Name: "go1.21.5", SHA: "6018ad99a4a951581b2d846a8ccd6f1d4e74fd11", Timestamp: "2023-12-05T18:12:56Z"},
|
||||
"go1.21.6": {Name: "go1.21.6", SHA: "cc85462b3d23193e4861813ea85e254cfe372403", Timestamp: "2024-01-09T18:17:19Z"},
|
||||
"go1.21.7": {Name: "go1.21.7", SHA: "f29208030ab80769ce61dedb5a419821abf92113", Timestamp: "2024-02-06T18:00:12Z"},
|
||||
"go1.21rc1": {Name: "go1.21rc1", SHA: "1c1c82432a78b06c8010c7257df58ff11cc05b61", Timestamp: "2023-06-16T14:21:46Z"},
|
||||
"go1.21rc2": {Name: "go1.21rc2", SHA: "d8117459c513e048eb72f11988d5416110dff359", Timestamp: "2023-06-21T15:40:05Z"},
|
||||
"go1.21rc3": {Name: "go1.21rc3", SHA: "4aeac326b5cb41a24d6e48c01008abf2f0fda7ff", Timestamp: "2023-07-14T15:07:26Z"},
|
||||
"go1.21rc4": {Name: "go1.21rc4", SHA: "041dd5ce051caf72d64b6d5f2f975515b3676a71", Timestamp: "2023-08-02T13:51:49Z"},
|
||||
"go1.22.0": {Name: "go1.22.0", SHA: "a10e42f219abb9c5bc4e7d86d9464700a42c7d57", Timestamp: "2024-02-06T22:28:04Z"},
|
||||
"go1.22rc1": {Name: "go1.22rc1", SHA: "fa72f3e034fdabc5922ac019281f53ea0a8328cf", Timestamp: "2023-12-19T20:59:26Z"},
|
||||
"go1.22rc2": {Name: "go1.22rc2", SHA: "1e1da4910546d7ef7e256011f165cb6be1d56451", Timestamp: "2024-01-24T16:35:35Z"},
|
||||
"go1.2rc2": {Name: "go1.2rc2", SHA: "309e16554aab1686c5bb744cababfbaa2d83db4d", Timestamp: "2013-10-18T04:53:33Z"},
|
||||
"go1.2rc3": {Name: "go1.2rc3", SHA: "2eb51b1ba8cbf593124ab95e2ea9efb5d3ddf21e", Timestamp: "2013-11-01T01:44:30Z"},
|
||||
"go1.2rc4": {Name: "go1.2rc4", SHA: "a5940dddba6e7995c6f7e4b4d11df17609c247be", Timestamp: "2013-11-13T04:29:48Z"},
|
||||
"go1.2rc5": {Name: "go1.2rc5", SHA: "4abdb873be5c4bbd1e0edec56f992b201d8e0e68", Timestamp: "2013-11-18T01:44:03Z"},
|
||||
"go1.3": {Name: "go1.3", SHA: "1cdd48c8a276cef9e3e20b7350d13556b6c96a71", Timestamp: "2014-06-19T00:20:01Z"},
|
||||
"go1.3.1": {Name: "go1.3.1", SHA: "1657de2d6dbb020e15908668f209f3be7dcef151", Timestamp: "2014-08-13T03:18:02Z"},
|
||||
"go1.3.2": {Name: "go1.3.2", SHA: "f3c81ed821268e2f2e2945b0816f495809bbdf21", Timestamp: "2014-09-25T22:32:20Z"},
|
||||
"go1.3.3": {Name: "go1.3.3", SHA: "3dbc53ae6ad4e3b93f31d35d98b38f6dda25f4ee", Timestamp: "2014-10-01T01:20:15Z"},
|
||||
"go1.3beta1": {Name: "go1.3beta1", SHA: "7ff8e90eb7ceb2016aa9fc736febd8a5902ec65e", Timestamp: "2014-04-22T00:00:27Z"},
|
||||
"go1.3beta2": {Name: "go1.3beta2", SHA: "c00043b5d8bd53130bddb5ef1e88643dccc4586f", Timestamp: "2014-05-21T00:46:08Z"},
|
||||
"go1.3rc1": {Name: "go1.3rc1", SHA: "a5565ec7d9c04843bc91c06a0d5a652716ee75a7", Timestamp: "2014-06-02T04:34:50Z"},
|
||||
"go1.3rc2": {Name: "go1.3rc2", SHA: "2a3daa8bdd5bd06808c51cb4f2921655f70d7617", Timestamp: "2014-06-13T03:24:50Z"},
|
||||
"go1.4": {Name: "go1.4", SHA: "c303df658d43b9f3e98e56e646f8e84a83495991", Timestamp: "2014-12-11T00:27:56Z"},
|
||||
"go1.4.1": {Name: "go1.4.1", SHA: "886b02d705ffb1be8b4974ac4c355d480a24e3ec", Timestamp: "2015-01-15T21:04:23Z"},
|
||||
"go1.4.2": {Name: "go1.4.2", SHA: "883bc6ed0ea815293fe6309d66f967ea60630e87", Timestamp: "2015-02-18T04:24:51Z"},
|
||||
"go1.4.3": {Name: "go1.4.3", SHA: "50eb39bb23e8b03e823c38e844f0410d0b5325d2", Timestamp: "2015-09-23T04:20:05Z"},
|
||||
"go1.4beta1": {Name: "go1.4beta1", SHA: "ca230d2d6ffeaef0be2f58fd46ba6ed34a8dbf46", Timestamp: "2014-10-30T01:02:58Z"},
|
||||
"go1.4rc1": {Name: "go1.4rc1", SHA: "30ef146819d031ccd875de806c4edad66366d4bc", Timestamp: "2014-11-17T02:55:59Z"},
|
||||
"go1.4rc2": {Name: "go1.4rc2", SHA: "3d344611770d03a9d2f822216074edd83af67677", Timestamp: "2014-12-02T02:43:43Z"},
|
||||
"go1.5": {Name: "go1.5", SHA: "bb03defe933c89fee44be675d7aa0fbd893ced30", Timestamp: "2015-08-19T05:04:37Z"},
|
||||
"go1.5.1": {Name: "go1.5.1", SHA: "f2e4c8b5fb3660d793b2c545ef207153db0a34b1", Timestamp: "2015-09-09T00:52:53Z"},
|
||||
"go1.5.2": {Name: "go1.5.2", SHA: "40cbf58f960a8f5287d2c3a93b3ca6119df67e85", Timestamp: "2015-12-03T00:44:15Z"},
|
||||
"go1.5.3": {Name: "go1.5.3", SHA: "27d5c0ede5b4411089f4bf52a41dd2f4eed36123", Timestamp: "2016-01-13T19:43:20Z"},
|
||||
"go1.5.4": {Name: "go1.5.4", SHA: "a1ef950a15517bca223d079a6cf65948c3db9694", Timestamp: "2016-04-11T23:39:07Z"},
|
||||
"go1.5beta1": {Name: "go1.5beta1", SHA: "b6ead9f171742cd5b519a22ecc690354b0d1ce27", Timestamp: "2015-07-07T21:53:11Z"},
|
||||
"go1.5beta2": {Name: "go1.5beta2", SHA: "cc8f5441980a8c2f9e6c8ec3222985ed488e76ba", Timestamp: "2015-07-17T03:34:11Z"},
|
||||
"go1.5beta3": {Name: "go1.5beta3", SHA: "d3ffc975f38890abbd8ca3f7833772e6423297e8", Timestamp: "2015-07-29T23:50:20Z"},
|
||||
"go1.5rc1": {Name: "go1.5rc1", SHA: "0d20a61e68ba22fb416fe2aa8b6532026822bad0", Timestamp: "2015-08-06T04:06:12Z"},
|
||||
"go1.6": {Name: "go1.6", SHA: "7bc40ffb05d8813bf9b41a331b45d37216f9e747", Timestamp: "2016-02-17T19:53:47Z"},
|
||||
"go1.6.1": {Name: "go1.6.1", SHA: "f5cf5673590a68c55b2330df9dfcdd6fac75b893", Timestamp: "2016-04-11T23:39:37Z"},
|
||||
"go1.6.2": {Name: "go1.6.2", SHA: "57e459e02b4b01567f92542f92cd9afde209e193", Timestamp: "2016-04-19T23:27:35Z"},
|
||||
"go1.6.3": {Name: "go1.6.3", SHA: "da6b9ec7bf1722fa00196e1eadc10a29156b6b28", Timestamp: "2016-07-18T15:36:26Z"},
|
||||
"go1.6.4": {Name: "go1.6.4", SHA: "aa1e69f3fc21795b6fab531a07008e0744ffe5bf", Timestamp: "2016-12-01T20:56:30Z"},
|
||||
"go1.6beta1": {Name: "go1.6beta1", SHA: "8db371b3d58a1c139f0854738f9962de05ca5d7a", Timestamp: "2015-12-17T22:45:50Z"},
|
||||
"go1.6beta2": {Name: "go1.6beta2", SHA: "66330d8c6c0a23b7eb48688f9954264e48b039da", Timestamp: "2016-01-13T23:40:13Z"},
|
||||
"go1.6rc1": {Name: "go1.6rc1", SHA: "036b8fd40b60830ca1d152f17148e52b96d8aa6c", Timestamp: "2016-01-28T00:06:14Z"},
|
||||
"go1.6rc2": {Name: "go1.6rc2", SHA: "5d343bdfb140970cc37f099064226d104ca6d817", Timestamp: "2016-02-03T23:11:17Z"},
|
||||
"go1.7": {Name: "go1.7", SHA: "0d818588685976407c81c60d2fda289361cbc8ec", Timestamp: "2016-08-15T22:43:38Z"},
|
||||
"go1.7.1": {Name: "go1.7.1", SHA: "f75aafdf56dd90eab75cfeac8cf69358f73ba171", Timestamp: "2016-09-07T19:11:54Z"},
|
||||
"go1.7.2": {Name: "go1.7.2", SHA: "edecc650ec95ac1a96d2312980e18d959f89835e", Timestamp: "2016-10-17T21:08:12Z"},
|
||||
"go1.7.3": {Name: "go1.7.3", SHA: "2f6557233c5a5c311547144c34b4045640ff9f71", Timestamp: "2016-10-19T17:04:39Z"},
|
||||
"go1.7.4": {Name: "go1.7.4", SHA: "6b36535cf382bce845dd2d272276e7ba350b0c6b", Timestamp: "2016-12-01T22:13:49Z"},
|
||||
"go1.7.5": {Name: "go1.7.5", SHA: "753452fac6f6963b5a6e38a239b05362385a3842", Timestamp: "2017-01-26T17:38:29Z"},
|
||||
"go1.7.6": {Name: "go1.7.6", SHA: "2b7a7b710f096b1b7e6f2ab5e9e3ec003ad7cd12", Timestamp: "2017-05-23T18:33:01Z"},
|
||||
"go1.7beta1": {Name: "go1.7beta1", SHA: "3c6b6684ce21c1092ba208a0f1744ad7c930248a", Timestamp: "2016-06-02T00:22:03Z"},
|
||||
"go1.7beta2": {Name: "go1.7beta2", SHA: "fca9fc52c831ab6af56e30f8c48062a99ded2580", Timestamp: "2016-06-16T19:45:33Z"},
|
||||
"go1.7rc1": {Name: "go1.7rc1", SHA: "53da5fd4d431881bb3583c9790db7735a6530a1b", Timestamp: "2016-07-08T03:48:20Z"},
|
||||
"go1.7rc2": {Name: "go1.7rc2", SHA: "0ebf6ce087388cdd501a02ff92f2f8cafc3e1378", Timestamp: "2016-07-18T15:36:41Z"},
|
||||
"go1.7rc3": {Name: "go1.7rc3", SHA: "8707f31c0abc6b607014e843b7cc188b3019daa9", Timestamp: "2016-07-21T21:19:33Z"},
|
||||
"go1.7rc4": {Name: "go1.7rc4", SHA: "c628d83ec5309cd679e16c734456fed1b9a85806", Timestamp: "2016-08-02T02:22:22Z"},
|
||||
"go1.7rc5": {Name: "go1.7rc5", SHA: "09fc3cc5df6b37b62a219bd4cacd8898a2328b76", Timestamp: "2016-08-02T23:34:48Z"},
|
||||
"go1.7rc6": {Name: "go1.7rc6", SHA: "1e933ed7c091bd8e077ffd123234af10a69e3978", Timestamp: "2016-08-08T18:42:30Z"},
|
||||
"go1.8": {Name: "go1.8", SHA: "cd6b6202dd1559b3ac63179b45f1833fcfbe7eca", Timestamp: "2017-02-16T17:12:24Z"},
|
||||
"go1.8.1": {Name: "go1.8.1", SHA: "a4c18f063b6659079ca2848ca217a0587dabc001", Timestamp: "2017-04-07T16:48:41Z"},
|
||||
"go1.8.2": {Name: "go1.8.2", SHA: "59870f9e19384c3155f603f799b61b401fa20cc9", Timestamp: "2017-05-23T18:32:59Z"},
|
||||
"go1.8.3": {Name: "go1.8.3", SHA: "352996a381701cfa0c16e8de29cbde8f3922182f", Timestamp: "2017-05-24T18:14:11Z"},
|
||||
"go1.8.4": {Name: "go1.8.4", SHA: "f5bcb9b8fe9dd8949d4682b74be6ba72e5d554fb", Timestamp: "2017-10-04T18:39:32Z"},
|
||||
"go1.8.5": {Name: "go1.8.5", SHA: "d4ccbd8833aa45819e903abfc4337555f1832d3c", Timestamp: "2017-10-25T18:57:21Z"},
|
||||
"go1.8.5rc4": {Name: "go1.8.5rc4", SHA: "fab5e254b2a03d3153f850774d87a79840740fe9", Timestamp: "2017-10-20T16:43:01Z"},
|
||||
"go1.8.5rc5": {Name: "go1.8.5rc5", SHA: "0ab2c8872d648bc155e41bf5a7ed0cfee133ff70", Timestamp: "2017-10-25T16:24:05Z"},
|
||||
"go1.8.6": {Name: "go1.8.6", SHA: "96c72e94687d1d78770a204f35993cb2cd3c91e4", Timestamp: "2018-01-23T03:33:54Z"},
|
||||
"go1.8.7": {Name: "go1.8.7", SHA: "357c9141369361101345f3048a6b2b3e149299d5", Timestamp: "2018-02-07T15:33:09Z"},
|
||||
"go1.8beta1": {Name: "go1.8beta1", SHA: "41908a54530120b68a79e0fd22b5e709d33cced0", Timestamp: "2016-12-01T02:54:21Z"},
|
||||
"go1.8beta2": {Name: "go1.8beta2", SHA: "9cd3c0662aa63eea8e7fae80f558fda9d646ba98", Timestamp: "2016-12-15T20:06:07Z"},
|
||||
"go1.8rc1": {Name: "go1.8rc1", SHA: "3de6e96e4b8147f5267a2e8218a7c780b09a434f", Timestamp: "2017-01-10T19:35:03Z"},
|
||||
"go1.8rc2": {Name: "go1.8rc2", SHA: "59f181b6fda68ece22882945853ca2df9dbf1c88", Timestamp: "2017-01-19T20:58:37Z"},
|
||||
"go1.8rc3": {Name: "go1.8rc3", SHA: "2a5f65a98ca483aad2dd74dc2636a7baecc59cf2", Timestamp: "2017-01-26T17:42:08Z"},
|
||||
"go1.9": {Name: "go1.9", SHA: "c8aec4095e089ff6ac50d18e97c3f46561f14f48", Timestamp: "2017-08-24T20:52:14Z"},
|
||||
"go1.9.1": {Name: "go1.9.1", SHA: "7f40c1214dd67cf171a347a5230da70bd8e10d32", Timestamp: "2017-10-04T18:39:31Z"},
|
||||
"go1.9.2": {Name: "go1.9.2", SHA: "2ea7d3461bb41d0ae12b56ee52d43314bcdb97f9", Timestamp: "2017-10-25T20:24:05Z"},
|
||||
"go1.9.3": {Name: "go1.9.3", SHA: "a563954b799c6921fc3666b4723d38413f442145", Timestamp: "2018-01-22T21:38:28Z"},
|
||||
"go1.9.4": {Name: "go1.9.4", SHA: "6732fcc06df713fc737cee5c5860bad87599bc6d", Timestamp: "2018-02-07T15:34:31Z"},
|
||||
"go1.9.5": {Name: "go1.9.5", SHA: "f69b0c627f94b7dcaf4ec654df8e0ffa4bf46957", Timestamp: "2018-03-29T06:06:28Z"},
|
||||
"go1.9.6": {Name: "go1.9.6", SHA: "20f58c6075aef1bb7327ab0691ae095f9412ab5b", Timestamp: "2018-04-30T19:04:08Z"},
|
||||
"go1.9.7": {Name: "go1.9.7", SHA: "7df09b4a03f9e53334672674ba7983d5e7128646", Timestamp: "2018-06-06T20:29:29Z"},
|
||||
"go1.9beta1": {Name: "go1.9beta1", SHA: "952ecbe0a27aadd184ca3e2c342beb464d6b1653", Timestamp: "2017-06-14T21:44:01Z"},
|
||||
"go1.9beta2": {Name: "go1.9beta2", SHA: "eab99a8d548f8ba864647ab171a44f0a5376a6b3", Timestamp: "2017-06-26T21:12:22Z"},
|
||||
"go1.9rc1": {Name: "go1.9rc1", SHA: "65c6c88a9442b91d8b2fd0230337b1fda4bb6cdf", Timestamp: "2017-07-24T19:35:04Z"},
|
||||
"go1.9rc2": {Name: "go1.9rc2", SHA: "048c9cfaacb6fe7ac342b0acd8ca8322b6c49508", Timestamp: "2017-08-07T20:29:01Z"},
|
||||
}
|
139
vendor/github.com/go-delve/gore/macho.go
generated
vendored
139
vendor/github.com/go-delve/gore/macho.go
generated
vendored
@ -1,139 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"debug/gosym"
|
||||
"debug/macho"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func openMachO(fp string) (*machoFile, error) {
|
||||
osFile, err := os.Open(fp)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error when opening the file: %w", err)
|
||||
}
|
||||
|
||||
f, err := macho.NewFile(osFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error when parsing the Mach-O file: %w", err)
|
||||
}
|
||||
return &machoFile{file: f, osFile: osFile}, nil
|
||||
}
|
||||
|
||||
type machoFile struct {
|
||||
file *macho.File
|
||||
osFile *os.File
|
||||
}
|
||||
|
||||
func (m *machoFile) getFile() *os.File {
|
||||
return m.osFile
|
||||
}
|
||||
|
||||
func (m *machoFile) Close() error {
|
||||
err := m.file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.osFile.Close()
|
||||
}
|
||||
|
||||
func (m *machoFile) getPCLNTab() (*gosym.Table, error) {
|
||||
section := m.file.Section("__gopclntab")
|
||||
if section == nil {
|
||||
return nil, ErrNoPCLNTab
|
||||
}
|
||||
data, err := section.Data()
|
||||
if data == nil {
|
||||
return nil, err
|
||||
}
|
||||
pcln := gosym.NewLineTable(data, m.file.Section("__text").Addr)
|
||||
return gosym.NewTable(nil, pcln)
|
||||
}
|
||||
|
||||
func (m *machoFile) getRData() ([]byte, error) {
|
||||
_, data, err := m.getSectionData("__rodata")
|
||||
return data, err
|
||||
}
|
||||
|
||||
func (m *machoFile) getCodeSection() ([]byte, error) {
|
||||
_, data, err := m.getSectionData("__text")
|
||||
return data, err
|
||||
}
|
||||
|
||||
func (m *machoFile) getSectionDataFromOffset(off uint64) (uint64, []byte, error) {
|
||||
for _, section := range m.file.Sections {
|
||||
if section.Offset == 0 {
|
||||
// Only exist in memory
|
||||
continue
|
||||
}
|
||||
|
||||
if section.Addr <= off && off < (section.Addr+section.Size) {
|
||||
data, err := section.Data()
|
||||
return section.Addr, data, err
|
||||
}
|
||||
}
|
||||
return 0, nil, ErrSectionDoesNotExist
|
||||
}
|
||||
|
||||
func (m *machoFile) getSectionData(s string) (uint64, []byte, error) {
|
||||
section := m.file.Section(s)
|
||||
if section == nil {
|
||||
return 0, nil, ErrSectionDoesNotExist
|
||||
}
|
||||
data, err := section.Data()
|
||||
return section.Addr, data, err
|
||||
}
|
||||
|
||||
func (m *machoFile) getFileInfo() *FileInfo {
|
||||
fi := &FileInfo{
|
||||
ByteOrder: m.file.ByteOrder,
|
||||
OS: "macOS",
|
||||
}
|
||||
switch m.file.Cpu {
|
||||
case macho.Cpu386:
|
||||
fi.WordSize = intSize32
|
||||
fi.Arch = Arch386
|
||||
case macho.CpuAmd64:
|
||||
fi.WordSize = intSize64
|
||||
fi.Arch = ArchAMD64
|
||||
case macho.CpuArm64:
|
||||
fi.WordSize = intSize64
|
||||
fi.Arch = ArchARM64
|
||||
default:
|
||||
panic("Unsupported architecture")
|
||||
}
|
||||
return fi
|
||||
}
|
||||
|
||||
func (m *machoFile) getPCLNTABData() (uint64, []byte, error) {
|
||||
return m.getSectionData("__gopclntab")
|
||||
}
|
||||
|
||||
func (m *machoFile) moduledataSection() string {
|
||||
return "__noptrdata"
|
||||
}
|
||||
|
||||
func (m *machoFile) getBuildID() (string, error) {
|
||||
data, err := m.getCodeSection()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get code section: %w", err)
|
||||
}
|
||||
return parseBuildIDFromRaw(data)
|
||||
}
|
53
vendor/github.com/go-delve/gore/modinfo.go
generated
vendored
53
vendor/github.com/go-delve/gore/modinfo.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"debug/buildinfo"
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNoBuildInfo is returned if the file has no build information available.
|
||||
ErrNoBuildInfo = errors.New("no build info available")
|
||||
)
|
||||
|
||||
// BuildInfo that was extracted from the file.
|
||||
type BuildInfo struct {
|
||||
// Compiler version. Can be nil.
|
||||
Compiler *GoVersion
|
||||
// ModInfo holds information about the Go modules in this file.
|
||||
// Can be nil.
|
||||
ModInfo *debug.BuildInfo
|
||||
}
|
||||
|
||||
func (f *GoFile) extractBuildInfo() (*BuildInfo, error) {
|
||||
info, err := buildinfo.Read(f.fh.getFile())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error when extracting build information: %w", err)
|
||||
}
|
||||
|
||||
result := &BuildInfo{
|
||||
Compiler: ResolveGoVersion(info.GoVersion),
|
||||
ModInfo: info,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
914
vendor/github.com/go-delve/gore/moduledata.go
generated
vendored
914
vendor/github.com/go-delve/gore/moduledata.go
generated
vendored
@ -1,914 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2022 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Moduledata extracts the file's moduledata.
|
||||
func (f *GoFile) Moduledata() (Moduledata, error) {
|
||||
// We need the Go version to be defined to find the module data.
|
||||
ver, err := f.GetCompilerVersion()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get the Go version for the moduledata extraction: %w", err)
|
||||
}
|
||||
f.FileInfo.goversion = ver
|
||||
|
||||
md, err := parseModuledata(f.FileInfo, f.fh)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error when parsing the moduledata: %w", err)
|
||||
}
|
||||
|
||||
return md, nil
|
||||
}
|
||||
|
||||
// Moduledata holds information about the layout of the executable image in memory.
|
||||
type Moduledata interface {
|
||||
// Text returns the text secion.
|
||||
Text() ModuleDataSection
|
||||
// NoPtrData returns the noptrdata section.
|
||||
NoPtrData() ModuleDataSection
|
||||
// Data returns the data section.
|
||||
Data() ModuleDataSection
|
||||
// Bss returns the bss section.
|
||||
Bss() ModuleDataSection
|
||||
// NoPtrBss returns the noptrbss section.
|
||||
NoPtrBss() ModuleDataSection
|
||||
// Types returns the types section.
|
||||
Types() ModuleDataSection
|
||||
// PCLNTab returns the pclntab section.
|
||||
PCLNTab() ModuleDataSection
|
||||
// FuncTab returns the functab section.
|
||||
FuncTab() ModuleDataSection
|
||||
// ITabLinks returns the itablinks section.
|
||||
ITabLinks() ModuleDataSection
|
||||
// TypeLink returns the typelink section.
|
||||
TypeLink() ([]int32, error)
|
||||
// GoFuncValue returns the value of the 'go:func.*' symbol.
|
||||
GoFuncValue() uint64
|
||||
}
|
||||
|
||||
type moduledata struct {
|
||||
TextAddr, TextLen uint64
|
||||
NoPtrDataAddr, NoPtrDataLen uint64
|
||||
DataAddr, DataLen uint64
|
||||
BssAddr, BssLen uint64
|
||||
NoPtrBssAddr, NoPtrBssLen uint64
|
||||
|
||||
TypesAddr, TypesLen uint64
|
||||
TypelinkAddr, TypelinkLen uint64
|
||||
ITabLinkAddr, ITabLinkLen uint64
|
||||
FuncTabAddr, FuncTabLen uint64
|
||||
PCLNTabAddr, PCLNTabLen uint64
|
||||
|
||||
GoFuncVal uint64
|
||||
|
||||
fh fileHandler
|
||||
}
|
||||
|
||||
// Text returns the text secion.
|
||||
func (m moduledata) Text() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.TextAddr,
|
||||
Length: m.TextLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// NoPtrData returns the noptrdata section.
|
||||
func (m moduledata) NoPtrData() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.NoPtrDataAddr,
|
||||
Length: m.NoPtrDataLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// Data returns the data section.
|
||||
func (m moduledata) Data() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.DataAddr,
|
||||
Length: m.DataLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// Bss returns the bss section.
|
||||
func (m moduledata) Bss() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.BssAddr,
|
||||
Length: m.BssLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// NoPtrBss returns the noptrbss section.
|
||||
func (m moduledata) NoPtrBss() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.NoPtrBssAddr,
|
||||
Length: m.NoPtrBssLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// Types returns the types section.
|
||||
func (m moduledata) Types() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.TypesAddr,
|
||||
Length: m.TypesLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// PCLNTab returns the pclntab section.
|
||||
func (m moduledata) PCLNTab() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.PCLNTabAddr,
|
||||
Length: m.PCLNTabLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// FuncTab returns the functab section.
|
||||
func (m moduledata) FuncTab() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.FuncTabAddr,
|
||||
Length: m.FuncTabLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// ITabLinks returns the itablinks section.
|
||||
func (m moduledata) ITabLinks() ModuleDataSection {
|
||||
return ModuleDataSection{
|
||||
Address: m.ITabLinkAddr,
|
||||
Length: m.ITabLinkLen,
|
||||
fh: m.fh,
|
||||
}
|
||||
}
|
||||
|
||||
// TypeLink returns the typelink section.
|
||||
func (m moduledata) TypeLink() ([]int32, error) {
|
||||
base, data, err := m.fh.getSectionDataFromOffset(m.TypelinkAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get the typelink data section: %w", err)
|
||||
}
|
||||
|
||||
r := bytes.NewReader(data[m.TypelinkAddr-base:])
|
||||
a := make([]int32, 0, m.TypelinkLen)
|
||||
bo := m.fh.getFileInfo().ByteOrder
|
||||
for i := uint64(0); i < m.TypelinkLen; i++ {
|
||||
// Type offsets are always int32
|
||||
var off int32
|
||||
err = binary.Read(r, bo, &off)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read typelink item %d: %w", i, err)
|
||||
}
|
||||
a = append(a, off)
|
||||
}
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// GoFuncValue returns the value of the "go:func.*" symbol.
|
||||
func (m moduledata) GoFuncValue() uint64 {
|
||||
return m.GoFuncVal
|
||||
}
|
||||
|
||||
// ModuleDataSection is a section defined in the Moduledata structure.
|
||||
type ModuleDataSection struct {
|
||||
// Address is the virtual address where the section start.
|
||||
Address uint64
|
||||
// Length is the byte length for the data in this section.
|
||||
Length uint64
|
||||
fh fileHandler
|
||||
}
|
||||
|
||||
// Data returns the data in the section.
|
||||
func (m ModuleDataSection) Data() ([]byte, error) {
|
||||
// If we don't have any data, return an empty slice.
|
||||
if m.Length == 0 {
|
||||
return []byte{}, nil
|
||||
}
|
||||
base, data, err := m.fh.getSectionDataFromOffset(m.Address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting module data section failed: %w", err)
|
||||
}
|
||||
start := m.Address - base
|
||||
if uint64(len(data)) < start+m.Length {
|
||||
return nil, fmt.Errorf("the length of module data section is to big: address 0x%x, base 0x%x, length 0x%x", m.Address, base, m.Length)
|
||||
}
|
||||
buf := make([]byte, m.Length)
|
||||
copy(buf, data[start:start+m.Length])
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func findModuledata(f fileHandler) ([]byte, error) {
|
||||
_, secData, err := f.getSectionData(f.moduledataSection())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tabAddr, _, err := f.getPCLNTABData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Search for moduledata
|
||||
buf := new(bytes.Buffer)
|
||||
err = binary.Write(buf, binary.LittleEndian, &tabAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
off := bytes.Index(secData, buf.Bytes()[:intSize32])
|
||||
if off == -1 {
|
||||
return nil, errors.New("could not find moduledata")
|
||||
}
|
||||
// TODO: Verify that hit is correct.
|
||||
|
||||
return secData[off : off+0x300], nil
|
||||
}
|
||||
|
||||
func parseModuledata(fileInfo *FileInfo, f fileHandler) (moduledata, error) {
|
||||
data, err := findModuledata(f)
|
||||
if err != nil {
|
||||
return moduledata{}, err
|
||||
}
|
||||
|
||||
// buf will hold the struct type that represents the data in the file we are processing.
|
||||
var buf interface{}
|
||||
is32bit := fileInfo.WordSize == intSize32
|
||||
|
||||
// Determine what kind of struct we need to extract the module data from the file.
|
||||
|
||||
if GoVersionCompare("go1.20rc1", fileInfo.goversion.Name) <= 0 {
|
||||
if is32bit {
|
||||
buf = &moduledata2032{}
|
||||
} else {
|
||||
buf = &moduledata2064{}
|
||||
}
|
||||
} else if GoVersionCompare("go1.18beta1", fileInfo.goversion.Name) <= 0 {
|
||||
if is32bit {
|
||||
buf = &moduledata1832{}
|
||||
} else {
|
||||
buf = &moduledata1864{}
|
||||
}
|
||||
} else if GoVersionCompare("go1.16beta1", fileInfo.goversion.Name) <= 0 {
|
||||
if is32bit {
|
||||
buf = &moduledata1632{}
|
||||
} else {
|
||||
buf = &moduledata1664{}
|
||||
}
|
||||
} else if GoVersionCompare("go1.8beta1", fileInfo.goversion.Name) <= 0 {
|
||||
if is32bit {
|
||||
buf = &moduledata832{}
|
||||
} else {
|
||||
buf = &moduledata864{}
|
||||
}
|
||||
} else if GoVersionCompare("go1.7beta1", fileInfo.goversion.Name) <= 0 {
|
||||
if is32bit {
|
||||
buf = &moduledata732{}
|
||||
} else {
|
||||
buf = &moduledata764{}
|
||||
}
|
||||
} else {
|
||||
if is32bit {
|
||||
buf = &moduledata532{}
|
||||
} else {
|
||||
buf = &moduledata564{}
|
||||
}
|
||||
}
|
||||
|
||||
// Read the module struct from the file.
|
||||
r := bytes.NewReader(data)
|
||||
err = readStruct(r, fileInfo.ByteOrder, buf)
|
||||
if err != nil {
|
||||
return moduledata{}, fmt.Errorf("error when reading module data from file: %w", err)
|
||||
}
|
||||
|
||||
// Convert the read struct to the type we return to the caller.
|
||||
md, err := processModuledata(buf)
|
||||
if err != nil {
|
||||
return md, fmt.Errorf("error when processing module data: %w", err)
|
||||
}
|
||||
|
||||
// Add the file handler.
|
||||
md.fh = f
|
||||
|
||||
return md, nil
|
||||
}
|
||||
|
||||
func readUIntTo64(r io.Reader, byteOrder binary.ByteOrder, is32bit bool) (uint64, error) {
|
||||
if is32bit {
|
||||
var addr uint32
|
||||
err := binary.Read(r, byteOrder, &addr)
|
||||
return uint64(addr), err
|
||||
}
|
||||
var addr uint64
|
||||
err := binary.Read(r, byteOrder, &addr)
|
||||
return addr, err
|
||||
}
|
||||
|
||||
// readStruct performs a binary read from the reader to the data object. Data object must
|
||||
// be a pointer to the struct.
|
||||
func readStruct(r io.Reader, byteOrder binary.ByteOrder, data interface{}) error {
|
||||
return binary.Read(r, byteOrder, data)
|
||||
}
|
||||
|
||||
func processModuledata(data interface{}) (moduledata, error) {
|
||||
md := moduledata{}
|
||||
// This will panic if the data passed in is not a pointer to
|
||||
// a struct. But this function should not be called outside
|
||||
// of this file, we can ensure this is always the case.
|
||||
val := reflect.ValueOf(data).Elem()
|
||||
|
||||
extractModFieldValue(&md, "TextAddr", val, "Text")
|
||||
extractModFieldValue(&md, "TextLen", val, "Etext")
|
||||
if md.TextLen > md.TextAddr {
|
||||
md.TextLen = md.TextLen - md.TextAddr
|
||||
}
|
||||
|
||||
extractModFieldValue(&md, "NoPtrDataAddr", val, "Noptrdata")
|
||||
extractModFieldValue(&md, "NoPtrDataLen", val, "Enoptrdata")
|
||||
if md.NoPtrDataLen > md.NoPtrDataAddr {
|
||||
md.NoPtrDataLen = md.NoPtrDataLen - md.NoPtrDataAddr
|
||||
}
|
||||
|
||||
extractModFieldValue(&md, "DataAddr", val, "Data")
|
||||
extractModFieldValue(&md, "DataLen", val, "Edata")
|
||||
if md.DataLen > md.DataAddr {
|
||||
md.DataLen = md.DataLen - md.DataAddr
|
||||
}
|
||||
|
||||
extractModFieldValue(&md, "BssAddr", val, "Bss")
|
||||
extractModFieldValue(&md, "BssLen", val, "Ebss")
|
||||
if md.BssLen > md.BssAddr {
|
||||
md.BssLen = md.BssLen - md.BssAddr
|
||||
}
|
||||
|
||||
extractModFieldValue(&md, "NoPtrBssAddr", val, "Noptrbss")
|
||||
extractModFieldValue(&md, "NoPtrBssLen", val, "Enoptrbss")
|
||||
if md.NoPtrBssLen > md.NoPtrBssAddr {
|
||||
md.NoPtrBssLen = md.NoPtrBssLen - md.NoPtrBssAddr
|
||||
}
|
||||
|
||||
extractModFieldValue(&md, "TypelinkAddr", val, "Typelinks")
|
||||
extractModFieldValue(&md, "TypelinkLen", val, "Typelinkslen")
|
||||
extractModFieldValue(&md, "ITabLinkAddr", val, "Itablinks")
|
||||
extractModFieldValue(&md, "ITabLinkLen", val, "Itablinkslen")
|
||||
extractModFieldValue(&md, "FuncTabAddr", val, "Ftab")
|
||||
extractModFieldValue(&md, "FuncTabLen", val, "Ftablen")
|
||||
extractModFieldValue(&md, "PCLNTabAddr", val, "Pclntable")
|
||||
extractModFieldValue(&md, "PCLNTabLen", val, "Pclntablelen")
|
||||
|
||||
extractModFieldValue(&md, "TypesAddr", val, "Types")
|
||||
extractModFieldValue(&md, "TypesLen", val, "Etypes")
|
||||
if md.TypesLen > md.TypesAddr {
|
||||
md.TypesLen = md.TypesLen - md.TypesAddr
|
||||
}
|
||||
|
||||
extractModFieldValue(&md, "GoFuncVal", val, "GoFunc")
|
||||
|
||||
return md, nil
|
||||
}
|
||||
|
||||
func extractModFieldValue(md *moduledata, dst string, val reflect.Value, src string) {
|
||||
field := val.FieldByName(src)
|
||||
// Not all versions of the module struct has all the fields. If we don't have the
|
||||
// field, we skip it.
|
||||
if !field.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
// Save 32 to 64 uint casting if needed.
|
||||
var num uint64
|
||||
switch field.Interface().(type) {
|
||||
case uint64:
|
||||
num = field.Uint()
|
||||
case uint32:
|
||||
t := field.Interface().(uint32)
|
||||
num = uint64(t)
|
||||
}
|
||||
|
||||
// Set the value.
|
||||
mdField := reflect.ValueOf(md).Elem().FieldByName(dst)
|
||||
mdField.SetUint(num)
|
||||
}
|
||||
|
||||
/*
|
||||
Internal module structures from Go's runtime.
|
||||
*/
|
||||
|
||||
// Moduledata structure for Go 1.20 and newer
|
||||
|
||||
type moduledata2064 struct {
|
||||
PcHeader uint64
|
||||
Funcnametab, Funcnametablen, Funcnametabcap uint64
|
||||
Cutab, Cutablen, Cutabcap uint64
|
||||
Filetab, Filetablen, Filetabcap uint64
|
||||
Pctab, Pctablen, Pctabcap uint64
|
||||
Pclntable, Pclntablelen, Pclntablecap uint64
|
||||
Ftab, Ftablen, Ftabcap uint64
|
||||
Findfunctab uint64
|
||||
Minpc, Maxpc uint64
|
||||
|
||||
Text, Etext uint64
|
||||
Noptrdata, Enoptrdata uint64
|
||||
Data, Edata uint64
|
||||
Bss, Ebss uint64
|
||||
Noptrbss, Enoptrbss uint64
|
||||
Covctrs, Ecovctrs uint64
|
||||
End, Gcdata, Gcbss uint64
|
||||
Types, Etypes uint64
|
||||
RData uint64
|
||||
GoFunc uint64
|
||||
|
||||
Textsectmap, Textsectmaplen, Textsectmapcap uint64
|
||||
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint64
|
||||
|
||||
Ptab, Ptablen, Ptabcap uint64
|
||||
|
||||
Pluginpath, Pluginpathlen uint64
|
||||
Pkghashes, Pkghasheslen, Pkghashescap uint64
|
||||
|
||||
Modulename, Modulenamelen uint64
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
bad bool // module failed to load and should be ignored
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
type moduledata2032 struct {
|
||||
PcHeader uint32
|
||||
Funcnametab, Funcnametablen, Funcnametabcap uint32
|
||||
Cutab, Cutablen, Cutabcap uint32
|
||||
Filetab, Filetablen, Filetabcap uint32
|
||||
Pctab, Pctablen, Pctabcap uint32
|
||||
Pclntable, Pclntablelen, Pclntablecap uint32
|
||||
Ftab, Ftablen, Ftabcap uint32
|
||||
Findfunctab uint32
|
||||
Minpc, Maxpc uint32
|
||||
|
||||
Text, Etext uint32
|
||||
Noptrdata, Enoptrdata uint32
|
||||
Data, Edata uint32
|
||||
Bss, Ebss uint32
|
||||
Noptrbss, Enoptrbss uint32
|
||||
Covctrs, Ecovctrs uint32
|
||||
End, Gcdata, Gcbss uint32
|
||||
Types, Etypes uint32
|
||||
RData uint32
|
||||
GoFunc uint32
|
||||
|
||||
Textsectmap, Textsectmaplen, Textsectmapcap uint32
|
||||
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint32
|
||||
|
||||
Ptab, Ptablen, Ptabcap uint32
|
||||
|
||||
Pluginpath, Pluginpathlen uint32
|
||||
Pkghashes, Pkghasheslen, Pkghashescap uint32
|
||||
|
||||
Modulename, Modulenamelen uint32
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
bad bool // module failed to load and should be ignored
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
// Moduledata structure for Go 1.18 and Go 1.19
|
||||
|
||||
type moduledata1864 struct {
|
||||
PcHeader uint64
|
||||
Funcnametab, Funcnametablen, Funcnametabcap uint64
|
||||
Cutab, Cutablen, Cutabcap uint64
|
||||
Filetab, Filetablen, Filetabcap uint64
|
||||
Pctab, Pctablen, Pctabcap uint64
|
||||
Pclntable, Pclntablelen, Pclntablecap uint64
|
||||
Ftab, Ftablen, Ftabcap uint64
|
||||
Findfunctab uint64
|
||||
Minpc, Maxpc uint64
|
||||
|
||||
Text, Etext uint64
|
||||
Noptrdata, Enoptrdata uint64
|
||||
Data, Edata uint64
|
||||
Bss, Ebss uint64
|
||||
Noptrbss, Enoptrbss uint64
|
||||
End, Gcdata, Gcbss uint64
|
||||
Types, Etypes uint64
|
||||
RData uint64
|
||||
GoFunc uint64
|
||||
|
||||
Textsectmap, Textsectmaplen, Textsectmapcap uint64
|
||||
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint64
|
||||
|
||||
Ptab, Ptablen, Ptabcap uint64
|
||||
|
||||
Pluginpath, Pluginpathlen uint64
|
||||
Pkghashes, Pkghasheslen, Pkghashescap uint64
|
||||
|
||||
Modulename, Modulenamelen uint64
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
bad bool // module failed to load and should be ignored
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
type moduledata1832 struct {
|
||||
PcHeader uint32
|
||||
Funcnametab, Funcnametablen, Funcnametabcap uint32
|
||||
Cutab, Cutablen, Cutabcap uint32
|
||||
Filetab, Filetablen, Filetabcap uint32
|
||||
Pctab, Pctablen, Pctabcap uint32
|
||||
Pclntable, Pclntablelen, Pclntablecap uint32
|
||||
Ftab, Ftablen, Ftabcap uint32
|
||||
Findfunctab uint32
|
||||
Minpc, Maxpc uint32
|
||||
|
||||
Text, Etext uint32
|
||||
Noptrdata, Enoptrdata uint32
|
||||
Data, Edata uint32
|
||||
Bss, Ebss uint32
|
||||
Noptrbss, Enoptrbss uint32
|
||||
End, Gcdata, Gcbss uint32
|
||||
Types, Etypes uint32
|
||||
RData uint32
|
||||
GoFunc uint32
|
||||
|
||||
Textsectmap, Textsectmaplen, Textsectmapcap uint32
|
||||
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint32
|
||||
|
||||
Ptab, Ptablen, Ptabcap uint32
|
||||
|
||||
Pluginpath, Pluginpathlen uint32
|
||||
Pkghashes, Pkghasheslen, Pkghashescap uint32
|
||||
|
||||
Modulename, Modulenamelen uint32
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
bad bool // module failed to load and should be ignored
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
// Moduledata structure for Go 1.16 to 1.17
|
||||
|
||||
type moduledata1664 struct {
|
||||
PcHeader uint64
|
||||
Funcnametab, Funcnametablen, Funcnametabcap uint64
|
||||
Cutab, Cutablen, Cutabcap uint64
|
||||
Filetab, Filetablen, Filetabcap uint64
|
||||
Pctab, Pctablen, Pctabcap uint64
|
||||
Pclntable, Pclntablelen, Pclntablecap uint64
|
||||
Ftab, Ftablen, Ftabcap uint64
|
||||
Findfunctab uint64
|
||||
Minpc, Maxpc uint64
|
||||
|
||||
Text, Etext uint64
|
||||
Noptrdata, Enoptrdata uint64
|
||||
Data, Edata uint64
|
||||
Bss, Ebss uint64
|
||||
Noptrbss, Enoptrbss uint64
|
||||
End, Gcdata, Gcbss uint64
|
||||
Types, Etypes uint64
|
||||
|
||||
Textsectmap, Textsectmaplen, Textsectmapcap uint64
|
||||
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint64
|
||||
|
||||
Ptab, Ptablen, Ptabcap uint64
|
||||
|
||||
Pluginpath, Pluginpathlen uint64
|
||||
Pkghashes, Pkghasheslen, Pkghashescap uint64
|
||||
|
||||
Modulename, Modulenamelen uint64
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
bad bool // module failed to load and should be ignored
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
type moduledata1632 struct {
|
||||
PcHeader uint32
|
||||
Funcnametab, Funcnametablen, Funcnametabcap uint32
|
||||
Cutab, Cutablen, Cutabcap uint32
|
||||
Filetab, Filetablen, Filetabcap uint32
|
||||
Pctab, Pctablen, Pctabcap uint32
|
||||
Pclntable, Pclntablelen, Pclntablecap uint32
|
||||
Ftab, Ftablen, Ftabcap uint32
|
||||
Findfunctab uint32
|
||||
Minpc, Maxpc uint32
|
||||
|
||||
Text, Etext uint32
|
||||
Noptrdata, Enoptrdata uint32
|
||||
Data, Edata uint32
|
||||
Bss, Ebss uint32
|
||||
Noptrbss, Enoptrbss uint32
|
||||
End, Gcdata, Gcbss uint32
|
||||
Types, Etypes uint32
|
||||
|
||||
Textsectmap, Textsectmaplen, Textsectmapcap uint32
|
||||
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint32
|
||||
|
||||
Ptab, Ptablen, Ptabcap uint32
|
||||
|
||||
Pluginpath, Pluginpathlen uint32
|
||||
Pkghashes, Pkghasheslen, Pkghashescap uint32
|
||||
|
||||
Modulename, Modulenamelen uint32
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
bad bool // module failed to load and should be ignored
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
// Moduledata structure for Go 1.8 to 1.15
|
||||
|
||||
type moduledata864 struct {
|
||||
Pclntable, Pclntablelen, Pclntablecap uint64
|
||||
Ftab, Ftablen, Ftabcap uint64
|
||||
Filetab, Filetablen, Filetabcap uint64
|
||||
Findfunctab uint64
|
||||
Minpc, Maxpc uint64
|
||||
|
||||
Text, Etext uint64
|
||||
Noptrdata, Enoptrdata uint64
|
||||
Data, Edata uint64
|
||||
Bss, Ebss uint64
|
||||
Noptrbss, Enoptrbss uint64
|
||||
End, Gcdata, Gcbss uint64
|
||||
Types, Etypes uint64
|
||||
|
||||
Textsectmap, Textsectmaplen, Textsectmapcap uint64
|
||||
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint64
|
||||
|
||||
Ptab, Ptablen, Ptabcap uint64
|
||||
|
||||
Pluginpath, Pluginpathlen uint64
|
||||
Pkghashes, Pkghasheslen, Pkghashescap uint64
|
||||
|
||||
Modulename, Modulenamelen uint64
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
bad bool // module failed to load and should be ignored
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
type moduledata832 struct {
|
||||
Pclntable, Pclntablelen, Pclntablecap uint32
|
||||
Ftab, Ftablen, Ftabcap uint32
|
||||
Filetab, Filetablen, Filetabcap uint32
|
||||
Findfunctab uint32
|
||||
Minpc, Maxpc uint32
|
||||
|
||||
Text, Etext uint32
|
||||
Noptrdata, Enoptrdata uint32
|
||||
Data, Edata uint32
|
||||
Bss, Ebss uint32
|
||||
Noptrbss, Enoptrbss uint32
|
||||
End, Gcdata, Gcbss uint32
|
||||
Types, Etypes uint32
|
||||
|
||||
Textsectmap, Textsectmaplen, Textsectmapcap uint32
|
||||
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint32
|
||||
|
||||
Ptab, Ptablen, Ptabcap uint32
|
||||
|
||||
Pluginpath, Pluginpathlen uint32
|
||||
Pkghashes, Pkghasheslen, Pkghashescap uint32
|
||||
|
||||
Modulename, Modulenamelen uint32
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
bad bool // module failed to load and should be ignored
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
// Moduledata structure for Go 1.7
|
||||
|
||||
type moduledata764 struct {
|
||||
Pclntable, Pclntablelen, Pclntablecap uint64
|
||||
Ftab, Ftablen, Ftabcap uint64
|
||||
Filetab, Filetablen, Filetabcap uint64
|
||||
Findfunctab uint64
|
||||
Minpc, Maxpc uint64
|
||||
|
||||
Text, Etext uint64
|
||||
Noptrdata, Enoptrdata uint64
|
||||
Data, Edata uint64
|
||||
Bss, Ebss uint64
|
||||
Noptrbss, Enoptrbss uint64
|
||||
End, Gcdata, Gcbss uint64
|
||||
Types, Etypes uint64
|
||||
|
||||
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint64
|
||||
|
||||
Modulename, Modulenamelen uint64
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
type moduledata732 struct {
|
||||
Pclntable, Pclntablelen, Pclntablecap uint32
|
||||
Ftab, Ftablen, Ftabcap uint32
|
||||
Filetab, Filetablen, Filetabcap uint32
|
||||
Findfunctab uint32
|
||||
Minpc, Maxpc uint32
|
||||
|
||||
Text, Etext uint32
|
||||
Noptrdata, Enoptrdata uint32
|
||||
Data, Edata uint32
|
||||
Bss, Ebss uint32
|
||||
Noptrbss, Enoptrbss uint32
|
||||
End, Gcdata, Gcbss uint32
|
||||
Types, Etypes uint32
|
||||
|
||||
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
||||
Itablinks, Itablinkslen, Itablinkscap uint32
|
||||
|
||||
Modulename, Modulenamelen uint32
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
// Moduledata structure for Go 1.5 to 1.6
|
||||
|
||||
type moduledata564 struct {
|
||||
Pclntable, Pclntablelen, Pclntablecap uint64
|
||||
Ftab, Ftablen, Ftabcap uint64
|
||||
Filetab, Filetablen, Filetabcap uint64
|
||||
Findfunctab uint64
|
||||
Minpc, Maxpc uint64
|
||||
|
||||
Text, Etext uint64
|
||||
Noptrdata, Enoptrdata uint64
|
||||
Data, Edata uint64
|
||||
Bss, Ebss uint64
|
||||
Noptrbss, Enoptrbss uint64
|
||||
End, Gcdata, Gcbss uint64
|
||||
|
||||
Typelinks, Typelinkslen, Typelinkscap uint64
|
||||
|
||||
Modulename, Modulenamelen uint64
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
||||
|
||||
type moduledata532 struct {
|
||||
Pclntable, Pclntablelen, Pclntablecap uint32
|
||||
Ftab, Ftablen, Ftabcap uint32
|
||||
Filetab, Filetablen, Filetabcap uint32
|
||||
Findfunctab uint32
|
||||
Minpc, Maxpc uint32
|
||||
|
||||
Text, Etext uint32
|
||||
Noptrdata, Enoptrdata uint32
|
||||
Data, Edata uint32
|
||||
Bss, Ebss uint32
|
||||
Noptrbss, Enoptrbss uint32
|
||||
End, Gcdata, Gcbss uint32
|
||||
|
||||
Typelinks, Typelinkslen, Typelinkscap uint32
|
||||
|
||||
Modulename, Modulenamelen uint32
|
||||
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
||||
|
||||
/* These fields we are not planning to use so skipping the parsing of them.
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
|
||||
next *moduledata
|
||||
*/
|
||||
}
|
300
vendor/github.com/go-delve/gore/package.go
generated
vendored
300
vendor/github.com/go-delve/gore/package.go
generated
vendored
@ -1,300 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:generate go run gen.go
|
||||
|
||||
var (
|
||||
knownRepos = []string{"golang.org", "github.com", "gitlab.com"}
|
||||
)
|
||||
|
||||
// Package is a representation of a Go package.
|
||||
type Package struct {
|
||||
// Name is the name of the package.
|
||||
Name string `json:"name"`
|
||||
// Filepath is the extracted file path for the package.
|
||||
Filepath string `json:"path"`
|
||||
// Functions is a list of functions that are part of the package.
|
||||
Functions []*Function `json:"functions"`
|
||||
// Methods a list of methods that are part of the package.
|
||||
Methods []*Method `json:"methods"`
|
||||
}
|
||||
|
||||
// GetSourceFiles returns a slice of source files within the package.
|
||||
// The source files are a representations of the source code files in the package.
|
||||
func (f *GoFile) GetSourceFiles(p *Package) []*SourceFile {
|
||||
tmp := make(map[string]*SourceFile)
|
||||
getSourceFile := func(fileName string) *SourceFile {
|
||||
sf, ok := tmp[fileName]
|
||||
if !ok {
|
||||
return &SourceFile{Name: filepath.Base(fileName)}
|
||||
}
|
||||
return sf
|
||||
}
|
||||
|
||||
// Sort functions and methods by source file.
|
||||
for _, fn := range p.Functions {
|
||||
fileName, _, _ := f.pclntab.PCToLine(fn.Offset)
|
||||
start, end := findSourceLines(fn.Offset, fn.End, f.pclntab)
|
||||
|
||||
e := FileEntry{Name: fn.Name, Start: start, End: end}
|
||||
|
||||
sf := getSourceFile(fileName)
|
||||
sf.entries = append(sf.entries, e)
|
||||
tmp[fileName] = sf
|
||||
}
|
||||
for _, m := range p.Methods {
|
||||
fileName, _, _ := f.pclntab.PCToLine(m.Offset)
|
||||
start, end := findSourceLines(m.Offset, m.End, f.pclntab)
|
||||
|
||||
e := FileEntry{Name: fmt.Sprintf("%s%s", m.Receiver, m.Name), Start: start, End: end}
|
||||
|
||||
sf := getSourceFile(fileName)
|
||||
sf.entries = append(sf.entries, e)
|
||||
tmp[fileName] = sf
|
||||
}
|
||||
|
||||
// Create final slice and populate it.
|
||||
files := make([]*SourceFile, len(tmp))
|
||||
i := 0
|
||||
for _, sf := range tmp {
|
||||
files[i] = sf
|
||||
i++
|
||||
}
|
||||
|
||||
// Sort the file list.
|
||||
sort.Slice(files, func(i, j int) bool {
|
||||
return files[i].Name < files[j].Name
|
||||
})
|
||||
return files
|
||||
}
|
||||
|
||||
// PackageClass is a type used to indicate the package kind.
|
||||
type PackageClass uint8
|
||||
|
||||
const (
|
||||
// ClassUnknown is used for packages that could not be classified.
|
||||
ClassUnknown PackageClass = iota
|
||||
// ClassSTD is used for packages that are part of the standard library.
|
||||
ClassSTD
|
||||
// ClassMain is used for the main package and its subpackages.
|
||||
ClassMain
|
||||
// ClassVendor is used for vendor packages.
|
||||
ClassVendor
|
||||
// ClassGenerated are used for packages generated by the compiler.
|
||||
ClassGenerated
|
||||
)
|
||||
|
||||
// PackageClassifier classifies a package to the correct class type.
|
||||
type PackageClassifier interface {
|
||||
// Classify performs the classification.
|
||||
Classify(pkg *Package) PackageClass
|
||||
}
|
||||
|
||||
// NewPathPackageClassifier constructs a new classifier based on the main package's filepath.
|
||||
func NewPathPackageClassifier(mainPkgFilepath string) *PathPackageClassifier {
|
||||
return &PathPackageClassifier{
|
||||
mainFilepath: mainPkgFilepath, mainFolders: []string{
|
||||
filepath.Dir(mainPkgFilepath),
|
||||
mainPkgFilepath,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// PathPackageClassifier can classify the class of a go package.
|
||||
type PathPackageClassifier struct {
|
||||
mainFilepath string
|
||||
mainFolders []string
|
||||
}
|
||||
|
||||
// Classify returns the package class for the package.
|
||||
func (c *PathPackageClassifier) Classify(pkg *Package) PackageClass {
|
||||
if pkg.Name == "type" || strings.HasPrefix(pkg.Name, "type..") {
|
||||
return ClassGenerated
|
||||
}
|
||||
|
||||
if IsStandardLibrary(pkg.Name) {
|
||||
return ClassSTD
|
||||
}
|
||||
|
||||
if isGeneratedPackage(pkg) {
|
||||
return ClassGenerated
|
||||
}
|
||||
|
||||
// Detect internal/golang.org/x/net/http2/hpack type/
|
||||
tmp := strings.Split(pkg.Name, "/golang.org")[0]
|
||||
if len(tmp) < len(pkg.Name) && IsStandardLibrary(tmp) {
|
||||
return ClassSTD
|
||||
}
|
||||
|
||||
// cgo packages.
|
||||
if strings.HasPrefix(pkg.Name, "_cgo_") || strings.HasPrefix(pkg.Name, "x_cgo_") {
|
||||
return ClassSTD
|
||||
}
|
||||
|
||||
// If the file path contains "@v", it's a 3rd party package.
|
||||
if strings.Contains(pkg.Filepath, "@v") {
|
||||
return ClassVendor
|
||||
}
|
||||
|
||||
parentFolder := filepath.Dir(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/") {
|
||||
return ClassVendor
|
||||
}
|
||||
|
||||
for _, folder := range c.mainFolders {
|
||||
if parentFolder == folder {
|
||||
return ClassMain
|
||||
}
|
||||
}
|
||||
|
||||
// If the package name starts with "vendor/" assume it's a vendor package.
|
||||
if strings.HasPrefix(pkg.Name, "vendor/") {
|
||||
return ClassVendor
|
||||
}
|
||||
|
||||
// Start with repo url.and has it in the path.
|
||||
for _, url := range knownRepos {
|
||||
if strings.HasPrefix(pkg.Name, url) && strings.Contains(pkg.Filepath, url) {
|
||||
return ClassVendor
|
||||
}
|
||||
}
|
||||
|
||||
// If the path does not contain the "vendor" in 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)) {
|
||||
return ClassMain
|
||||
}
|
||||
|
||||
// Special case for entry point package.
|
||||
if pkg.Name == "" && filepath.Base(pkg.Filepath) == "runtime" {
|
||||
return ClassSTD
|
||||
}
|
||||
|
||||
// At this point, if it's a subpackage of the main assume main.
|
||||
if strings.HasPrefix(pkg.Filepath, c.mainFilepath) {
|
||||
return ClassMain
|
||||
}
|
||||
|
||||
// Check if it's the main parent package.
|
||||
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.
|
||||
if c.mainFilepath == "command-line-arguments" {
|
||||
return ClassMain
|
||||
}
|
||||
|
||||
return ClassUnknown
|
||||
}
|
||||
|
||||
// IsStandardLibrary returns true if the package is from the standard library.
|
||||
// Otherwise, false is retuned.
|
||||
func IsStandardLibrary(pkg string) bool {
|
||||
_, ok := stdPkgs[pkg]
|
||||
return ok
|
||||
}
|
||||
|
||||
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) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Special case for no package name and path of ".".
|
||||
if pkg.Name == "" && pkg.Filepath == "." {
|
||||
return true
|
||||
}
|
||||
|
||||
// Some internal stuff, classify it as Generated
|
||||
if pkg.Filepath == "." && (pkg.Name == "__x86" || pkg.Name == "__i686") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// NewModPackageClassifier creates a new mod based package classifier.
|
||||
func NewModPackageClassifier(buildInfo *debug.BuildInfo) *ModPackageClassifier {
|
||||
return &ModPackageClassifier{modInfo: buildInfo}
|
||||
}
|
||||
|
||||
// ModPackageClassifier uses the mod info extracted from the binary to classify packages.
|
||||
type ModPackageClassifier struct {
|
||||
modInfo *debug.BuildInfo
|
||||
}
|
||||
|
||||
// Classify performs the classification.
|
||||
func (c *ModPackageClassifier) Classify(pkg *Package) PackageClass {
|
||||
if IsStandardLibrary(pkg.Name) {
|
||||
return ClassSTD
|
||||
}
|
||||
|
||||
// Main package.
|
||||
if pkg.Name == "main" {
|
||||
return ClassMain
|
||||
}
|
||||
|
||||
// If the build info path is not an empty string and the package has the path as a substring, it is part of the main module.
|
||||
if c.modInfo.Path != "" && (strings.HasPrefix(pkg.Filepath, c.modInfo.Path) || strings.HasPrefix(pkg.Name, c.modInfo.Path)) {
|
||||
return ClassMain
|
||||
}
|
||||
|
||||
// If the main module path is not an empty string and the package has the path as a substring, it is part of the main module.
|
||||
if c.modInfo.Main.Path != "" && (strings.HasPrefix(pkg.Filepath, c.modInfo.Main.Path) || strings.HasPrefix(pkg.Name, c.modInfo.Main.Path)) {
|
||||
return ClassMain
|
||||
}
|
||||
|
||||
// Check if the package is a direct dependency.
|
||||
for _, dep := range c.modInfo.Deps {
|
||||
if strings.HasPrefix(pkg.Filepath, dep.Path) || strings.HasPrefix(pkg.Name, dep.Path) {
|
||||
// If the vendor it matched on has the version of "(devel)", it is treated as part of
|
||||
// the main module.
|
||||
if dep.Version == "(devel)" {
|
||||
return ClassMain
|
||||
}
|
||||
return ClassVendor
|
||||
}
|
||||
}
|
||||
|
||||
if isGeneratedPackage(pkg) {
|
||||
return ClassGenerated
|
||||
}
|
||||
|
||||
// cgo packages.
|
||||
if strings.HasPrefix(pkg.Name, "_cgo_") || strings.HasPrefix(pkg.Name, "x_cgo_") {
|
||||
return ClassSTD
|
||||
}
|
||||
|
||||
// Only indirect dependencies should be left.
|
||||
return ClassVendor
|
||||
}
|
95
vendor/github.com/go-delve/gore/pclntab.go
generated
vendored
95
vendor/github.com/go-delve/gore/pclntab.go
generated
vendored
@ -1,95 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"debug/pe"
|
||||
)
|
||||
|
||||
// pclntab12magic is the magic bytes used for binaries compiled with Go
|
||||
// prior to 1.16
|
||||
var pclntab12magic = []byte{0xfb, 0xff, 0xff, 0xff, 0x0, 0x0}
|
||||
|
||||
// pclntab116magic is the magic bytes used for binaries compiled with
|
||||
// Go 1.16 and Go 1.17.
|
||||
var pclntab116magic = []byte{0xfa, 0xff, 0xff, 0xff, 0x0, 0x0}
|
||||
|
||||
// pclntab118magic is the magic bytes used for binaries compiled with
|
||||
// Go 1.18 and Go 1.19.
|
||||
var pclntab118magic = []byte{0xf0, 0xff, 0xff, 0xff, 0x0, 0x0}
|
||||
|
||||
// pclntab120magic is the magic bytes used for binaries compiled with
|
||||
// Go 1.20 and onwards.
|
||||
var pclntab120magic = []byte{0xf1, 0xff, 0xff, 0xff, 0x0, 0x0}
|
||||
|
||||
// searchFileForPCLNTab will search the .rdata and .text section for the
|
||||
// PCLN table. Note!! The address returned by this function needs to be
|
||||
// adjusted by adding the image base address!!!
|
||||
func searchFileForPCLNTab(f *pe.File) (uint32, []byte, error) {
|
||||
for _, v := range []string{".rdata", ".text"} {
|
||||
sec := f.Section(v)
|
||||
if sec == nil {
|
||||
continue
|
||||
}
|
||||
secData, err := sec.Data()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
tab, err := searchSectionForTab(secData)
|
||||
if err == ErrNoPCLNTab {
|
||||
continue
|
||||
}
|
||||
// TODO: Switch to returning a uint64 instead.
|
||||
addr := sec.VirtualAddress + uint32(len(secData)-len(tab))
|
||||
return addr, tab, err
|
||||
}
|
||||
return 0, []byte{}, ErrNoPCLNTab
|
||||
}
|
||||
|
||||
// searchSectionForTab looks for the PCLN table within the section.
|
||||
func searchSectionForTab(secData []byte) ([]byte, error) {
|
||||
// First check for the current magic used. If this fails, it could be
|
||||
// an older version. So check for the old header.
|
||||
MAGIC_LOOP:
|
||||
for _, magic := range [][]byte{pclntab120magic, pclntab118magic, pclntab116magic, pclntab12magic} {
|
||||
off := bytes.LastIndex(secData, magic)
|
||||
if off == -1 {
|
||||
continue // Try other magic.
|
||||
}
|
||||
for off != -1 {
|
||||
if off != 0 {
|
||||
buf := secData[off:]
|
||||
if len(buf) < 16 || buf[4] != 0 || buf[5] != 0 ||
|
||||
(buf[6] != 1 && buf[6] != 2 && buf[6] != 4) || // pc quantum
|
||||
(buf[7] != 4 && buf[7] != 8) { // pointer size
|
||||
// Header doesn't match.
|
||||
if off-1 <= 0 {
|
||||
continue MAGIC_LOOP
|
||||
}
|
||||
off = bytes.LastIndex(secData[:off-1], magic)
|
||||
continue
|
||||
}
|
||||
// Header match
|
||||
return secData[off:], nil
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil, ErrNoPCLNTab
|
||||
}
|
153
vendor/github.com/go-delve/gore/pe.go
generated
vendored
153
vendor/github.com/go-delve/gore/pe.go
generated
vendored
@ -1,153 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"debug/gosym"
|
||||
"debug/pe"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func openPE(fp string) (peF *peFile, err error) {
|
||||
// Parsing by the file by debug/pe can panic if the PE file is malformed.
|
||||
// To prevent a crash, we recover the panic and return it as an error
|
||||
// instead.
|
||||
go func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("error when processing PE file, probably corrupt: %s", r)
|
||||
}
|
||||
}()
|
||||
|
||||
osFile, err := os.Open(fp)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error when opening the file: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
f, err := pe.NewFile(osFile)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error when parsing the PE file: %w", err)
|
||||
return
|
||||
}
|
||||
peF = &peFile{file: f, osFile: osFile}
|
||||
return
|
||||
}
|
||||
|
||||
type peFile struct {
|
||||
file *pe.File
|
||||
osFile *os.File
|
||||
pclntabAddr uint64
|
||||
imageBase uint64
|
||||
}
|
||||
|
||||
func (p *peFile) getFile() *os.File {
|
||||
return p.osFile
|
||||
}
|
||||
|
||||
func (p *peFile) getPCLNTab() (*gosym.Table, error) {
|
||||
addr, pclndat, err := searchFileForPCLNTab(p.file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pcln := gosym.NewLineTable(pclndat, uint64(p.file.Section(".text").VirtualAddress)+p.imageBase)
|
||||
p.pclntabAddr = uint64(addr) + p.imageBase
|
||||
return gosym.NewTable(make([]byte, 0), pcln)
|
||||
}
|
||||
|
||||
func (p *peFile) Close() error {
|
||||
err := p.file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.osFile.Close()
|
||||
}
|
||||
|
||||
func (p *peFile) getRData() ([]byte, error) {
|
||||
section := p.file.Section(".rdata")
|
||||
if section == nil {
|
||||
return nil, ErrSectionDoesNotExist
|
||||
}
|
||||
return section.Data()
|
||||
}
|
||||
|
||||
func (p *peFile) getCodeSection() ([]byte, error) {
|
||||
section := p.file.Section(".text")
|
||||
if section == nil {
|
||||
return nil, ErrSectionDoesNotExist
|
||||
}
|
||||
return section.Data()
|
||||
}
|
||||
|
||||
func (p *peFile) moduledataSection() string {
|
||||
return ".data"
|
||||
}
|
||||
|
||||
func (p *peFile) getPCLNTABData() (uint64, []byte, error) {
|
||||
b, d, e := searchFileForPCLNTab(p.file)
|
||||
return p.imageBase + uint64(b), d, e
|
||||
}
|
||||
|
||||
func (p *peFile) getSectionDataFromOffset(off uint64) (uint64, []byte, error) {
|
||||
for _, section := range p.file.Sections {
|
||||
if section.Offset == 0 {
|
||||
// Only exist in memory
|
||||
continue
|
||||
}
|
||||
|
||||
if p.imageBase+uint64(section.VirtualAddress) <= off && off < p.imageBase+uint64(section.VirtualAddress+section.Size) {
|
||||
data, err := section.Data()
|
||||
return p.imageBase + uint64(section.VirtualAddress), data, err
|
||||
}
|
||||
}
|
||||
return 0, nil, ErrSectionDoesNotExist
|
||||
}
|
||||
|
||||
func (p *peFile) getSectionData(name string) (uint64, []byte, error) {
|
||||
section := p.file.Section(name)
|
||||
if section == nil {
|
||||
return 0, nil, ErrSectionDoesNotExist
|
||||
}
|
||||
data, err := section.Data()
|
||||
return p.imageBase + uint64(section.VirtualAddress), data, err
|
||||
}
|
||||
|
||||
func (p *peFile) getFileInfo() *FileInfo {
|
||||
fi := &FileInfo{ByteOrder: binary.LittleEndian, OS: "windows"}
|
||||
if p.file.Machine == pe.IMAGE_FILE_MACHINE_I386 {
|
||||
fi.WordSize = intSize32
|
||||
optHdr := p.file.OptionalHeader.(*pe.OptionalHeader32)
|
||||
p.imageBase = uint64(optHdr.ImageBase)
|
||||
fi.Arch = Arch386
|
||||
} else {
|
||||
fi.WordSize = intSize64
|
||||
optHdr := p.file.OptionalHeader.(*pe.OptionalHeader64)
|
||||
p.imageBase = optHdr.ImageBase
|
||||
fi.Arch = ArchAMD64
|
||||
}
|
||||
return fi
|
||||
}
|
||||
|
||||
func (p *peFile) getBuildID() (string, error) {
|
||||
data, err := p.getCodeSection()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get code section: %w", err)
|
||||
}
|
||||
return parseBuildIDFromRaw(data)
|
||||
}
|
503
vendor/github.com/go-delve/gore/stdpkg_gen.go
generated
vendored
503
vendor/github.com/go-delve/gore/stdpkg_gen.go
generated
vendored
@ -1,503 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated at
|
||||
// 2024-02-12 22:57:08.518965899 +0000 UTC
|
||||
|
||||
package gore
|
||||
|
||||
var stdPkgs = map[string]struct{}{
|
||||
"archive": {},
|
||||
"archive/tar": {},
|
||||
"archive/tar/testdata": {},
|
||||
"archive/zip": {},
|
||||
"archive/zip/testdata": {},
|
||||
"arena": {},
|
||||
"bufio": {},
|
||||
"builtin": {},
|
||||
"bytes": {},
|
||||
"cmp": {},
|
||||
"compress": {},
|
||||
"compress/bzip2": {},
|
||||
"compress/bzip2/testdata": {},
|
||||
"compress/flate": {},
|
||||
"compress/flate/testdata": {},
|
||||
"compress/gzip": {},
|
||||
"compress/gzip/testdata": {},
|
||||
"compress/lzw": {},
|
||||
"compress/testdata": {},
|
||||
"compress/zlib": {},
|
||||
"container": {},
|
||||
"container/heap": {},
|
||||
"container/list": {},
|
||||
"container/ring": {},
|
||||
"context": {},
|
||||
"crypto": {},
|
||||
"crypto/aes": {},
|
||||
"crypto/boring": {},
|
||||
"crypto/cipher": {},
|
||||
"crypto/des": {},
|
||||
"crypto/dsa": {},
|
||||
"crypto/ecdh": {},
|
||||
"crypto/ecdsa": {},
|
||||
"crypto/ecdsa/testdata": {},
|
||||
"crypto/ed25519": {},
|
||||
"crypto/ed25519/testdata": {},
|
||||
"crypto/elliptic": {},
|
||||
"crypto/hmac": {},
|
||||
"crypto/internal": {},
|
||||
"crypto/internal/alias": {},
|
||||
"crypto/internal/bigmod": {},
|
||||
"crypto/internal/bigmod/_asm": {},
|
||||
"crypto/internal/boring": {},
|
||||
"crypto/internal/boring/bbig": {},
|
||||
"crypto/internal/boring/bcache": {},
|
||||
"crypto/internal/boring/fipstls": {},
|
||||
"crypto/internal/boring/sig": {},
|
||||
"crypto/internal/boring/syso": {},
|
||||
"crypto/internal/edwards25519": {},
|
||||
"crypto/internal/edwards25519/field": {},
|
||||
"crypto/internal/edwards25519/field/_asm": {},
|
||||
"crypto/internal/nistec": {},
|
||||
"crypto/internal/nistec/fiat": {},
|
||||
"crypto/internal/randutil": {},
|
||||
"crypto/md5": {},
|
||||
"crypto/rand": {},
|
||||
"crypto/rc4": {},
|
||||
"crypto/rsa": {},
|
||||
"crypto/rsa/testdata": {},
|
||||
"crypto/sha1": {},
|
||||
"crypto/sha256": {},
|
||||
"crypto/sha512": {},
|
||||
"crypto/subtle": {},
|
||||
"crypto/tls": {},
|
||||
"crypto/tls/fipsonly": {},
|
||||
"crypto/tls/testdata": {},
|
||||
"crypto/x509": {},
|
||||
"crypto/x509/internal": {},
|
||||
"crypto/x509/internal/macos": {},
|
||||
"crypto/x509/pkix": {},
|
||||
"crypto/x509/testdata": {},
|
||||
"database": {},
|
||||
"database/sql": {},
|
||||
"database/sql/driver": {},
|
||||
"debug": {},
|
||||
"debug/buildinfo": {},
|
||||
"debug/dwarf": {},
|
||||
"debug/dwarf/testdata": {},
|
||||
"debug/elf": {},
|
||||
"debug/elf/testdata": {},
|
||||
"debug/gosym": {},
|
||||
"debug/gosym/testdata": {},
|
||||
"debug/macho": {},
|
||||
"debug/macho/testdata": {},
|
||||
"debug/pe": {},
|
||||
"debug/pe/testdata": {},
|
||||
"debug/plan9obj": {},
|
||||
"debug/plan9obj/testdata": {},
|
||||
"embed": {},
|
||||
"embed/internal": {},
|
||||
"embed/internal/embedtest": {},
|
||||
"embed/internal/embedtest/testdata": {},
|
||||
"embed/internal/embedtest/testdata/-not-hidden": {},
|
||||
"embed/internal/embedtest/testdata/.hidden": {},
|
||||
"embed/internal/embedtest/testdata/.hidden/.more": {},
|
||||
"embed/internal/embedtest/testdata/.hidden/_more": {},
|
||||
"embed/internal/embedtest/testdata/.hidden/more": {},
|
||||
"embed/internal/embedtest/testdata/_hidden": {},
|
||||
"embed/internal/embedtest/testdata/i": {},
|
||||
"embed/internal/embedtest/testdata/i/j": {},
|
||||
"embed/internal/embedtest/testdata/i/j/k": {},
|
||||
"encoding": {},
|
||||
"encoding/ascii85": {},
|
||||
"encoding/asn1": {},
|
||||
"encoding/base32": {},
|
||||
"encoding/base64": {},
|
||||
"encoding/binary": {},
|
||||
"encoding/csv": {},
|
||||
"encoding/gob": {},
|
||||
"encoding/hex": {},
|
||||
"encoding/json": {},
|
||||
"encoding/json/testdata": {},
|
||||
"encoding/pem": {},
|
||||
"encoding/xml": {},
|
||||
"errors": {},
|
||||
"expvar": {},
|
||||
"flag": {},
|
||||
"fmt": {},
|
||||
"go": {},
|
||||
"go/ast": {},
|
||||
"go/build": {},
|
||||
"go/build/constraint": {},
|
||||
"go/build/testdata": {},
|
||||
"go/build/testdata/alltags": {},
|
||||
"go/build/testdata/bads": {},
|
||||
"go/build/testdata/cgo_disabled": {},
|
||||
"go/build/testdata/directives": {},
|
||||
"go/build/testdata/doc": {},
|
||||
"go/build/testdata/empty": {},
|
||||
"go/build/testdata/multi": {},
|
||||
"go/build/testdata/non_source_tags": {},
|
||||
"go/build/testdata/other": {},
|
||||
"go/build/testdata/other/file": {},
|
||||
"go/build/testdata/withvendor": {},
|
||||
"go/build/testdata/withvendor/src": {},
|
||||
"go/build/testdata/withvendor/src/a": {},
|
||||
"go/build/testdata/withvendor/src/a/b": {},
|
||||
"go/build/testdata/withvendor/src/a/vendor": {},
|
||||
"go/build/testdata/withvendor/src/a/vendor/c": {},
|
||||
"go/build/testdata/withvendor/src/a/vendor/c/d": {},
|
||||
"go/constant": {},
|
||||
"go/doc": {},
|
||||
"go/doc/comment": {},
|
||||
"go/doc/comment/testdata": {},
|
||||
"go/doc/testdata": {},
|
||||
"go/doc/testdata/examples": {},
|
||||
"go/doc/testdata/pkgdoc": {},
|
||||
"go/format": {},
|
||||
"go/importer": {},
|
||||
"go/internal": {},
|
||||
"go/internal/gccgoimporter": {},
|
||||
"go/internal/gccgoimporter/testdata": {},
|
||||
"go/internal/gcimporter": {},
|
||||
"go/internal/gcimporter/testdata": {},
|
||||
"go/internal/gcimporter/testdata/versions": {},
|
||||
"go/internal/srcimporter": {},
|
||||
"go/internal/srcimporter/testdata": {},
|
||||
"go/internal/srcimporter/testdata/issue20855": {},
|
||||
"go/internal/srcimporter/testdata/issue23092": {},
|
||||
"go/internal/srcimporter/testdata/issue24392": {},
|
||||
"go/internal/typeparams": {},
|
||||
"go/parser": {},
|
||||
"go/parser/testdata": {},
|
||||
"go/parser/testdata/goversion": {},
|
||||
"go/parser/testdata/issue42951": {},
|
||||
"go/parser/testdata/issue42951/not_a_file.go": {},
|
||||
"go/parser/testdata/resolution": {},
|
||||
"go/printer": {},
|
||||
"go/printer/testdata": {},
|
||||
"go/scanner": {},
|
||||
"go/token": {},
|
||||
"go/types": {},
|
||||
"go/types/testdata": {},
|
||||
"go/types/testdata/local": {},
|
||||
"go/version": {},
|
||||
"hash": {},
|
||||
"hash/adler32": {},
|
||||
"hash/crc32": {},
|
||||
"hash/crc64": {},
|
||||
"hash/fnv": {},
|
||||
"hash/maphash": {},
|
||||
"html": {},
|
||||
"html/template": {},
|
||||
"html/template/testdata": {},
|
||||
"image": {},
|
||||
"image/color": {},
|
||||
"image/color/palette": {},
|
||||
"image/draw": {},
|
||||
"image/gif": {},
|
||||
"image/internal": {},
|
||||
"image/internal/imageutil": {},
|
||||
"image/jpeg": {},
|
||||
"image/png": {},
|
||||
"image/png/testdata": {},
|
||||
"image/png/testdata/pngsuite": {},
|
||||
"image/testdata": {},
|
||||
"index": {},
|
||||
"index/suffixarray": {},
|
||||
"internal": {},
|
||||
"internal/abi": {},
|
||||
"internal/abi/testdata": {},
|
||||
"internal/bisect": {},
|
||||
"internal/buildcfg": {},
|
||||
"internal/bytealg": {},
|
||||
"internal/cfg": {},
|
||||
"internal/chacha8rand": {},
|
||||
"internal/coverage": {},
|
||||
"internal/coverage/calloc": {},
|
||||
"internal/coverage/cformat": {},
|
||||
"internal/coverage/cmerge": {},
|
||||
"internal/coverage/decodecounter": {},
|
||||
"internal/coverage/decodemeta": {},
|
||||
"internal/coverage/encodecounter": {},
|
||||
"internal/coverage/encodemeta": {},
|
||||
"internal/coverage/pods": {},
|
||||
"internal/coverage/rtcov": {},
|
||||
"internal/coverage/slicereader": {},
|
||||
"internal/coverage/slicewriter": {},
|
||||
"internal/coverage/stringtab": {},
|
||||
"internal/coverage/test": {},
|
||||
"internal/coverage/uleb128": {},
|
||||
"internal/cpu": {},
|
||||
"internal/dag": {},
|
||||
"internal/diff": {},
|
||||
"internal/diff/testdata": {},
|
||||
"internal/fmtsort": {},
|
||||
"internal/fuzz": {},
|
||||
"internal/goarch": {},
|
||||
"internal/godebug": {},
|
||||
"internal/godebugs": {},
|
||||
"internal/goexperiment": {},
|
||||
"internal/goos": {},
|
||||
"internal/goroot": {},
|
||||
"internal/gover": {},
|
||||
"internal/goversion": {},
|
||||
"internal/intern": {},
|
||||
"internal/itoa": {},
|
||||
"internal/lazyregexp": {},
|
||||
"internal/lazytemplate": {},
|
||||
"internal/nettrace": {},
|
||||
"internal/obscuretestdata": {},
|
||||
"internal/oserror": {},
|
||||
"internal/pkgbits": {},
|
||||
"internal/platform": {},
|
||||
"internal/poll": {},
|
||||
"internal/profile": {},
|
||||
"internal/race": {},
|
||||
"internal/reflectlite": {},
|
||||
"internal/safefilepath": {},
|
||||
"internal/saferio": {},
|
||||
"internal/singleflight": {},
|
||||
"internal/syscall": {},
|
||||
"internal/syscall/execenv": {},
|
||||
"internal/syscall/unix": {},
|
||||
"internal/syscall/windows": {},
|
||||
"internal/syscall/windows/registry": {},
|
||||
"internal/syscall/windows/sysdll": {},
|
||||
"internal/sysinfo": {},
|
||||
"internal/testenv": {},
|
||||
"internal/testlog": {},
|
||||
"internal/testpty": {},
|
||||
"internal/trace": {},
|
||||
"internal/trace/testdata": {},
|
||||
"internal/trace/traceviewer": {},
|
||||
"internal/trace/traceviewer/format": {},
|
||||
"internal/trace/traceviewer/static": {},
|
||||
"internal/trace/v2": {},
|
||||
"internal/trace/v2/event": {},
|
||||
"internal/trace/v2/event/go122": {},
|
||||
"internal/trace/v2/internal": {},
|
||||
"internal/trace/v2/internal/testgen": {},
|
||||
"internal/trace/v2/internal/testgen/go122": {},
|
||||
"internal/trace/v2/raw": {},
|
||||
"internal/trace/v2/testdata": {},
|
||||
"internal/trace/v2/testdata/cmd": {},
|
||||
"internal/trace/v2/testdata/cmd/gotraceraw": {},
|
||||
"internal/trace/v2/testdata/cmd/gotracevalidate": {},
|
||||
"internal/trace/v2/testdata/fuzz": {},
|
||||
"internal/trace/v2/testdata/fuzz/FuzzReader": {},
|
||||
"internal/trace/v2/testdata/generators": {},
|
||||
"internal/trace/v2/testdata/testprog": {},
|
||||
"internal/trace/v2/testdata/tests": {},
|
||||
"internal/trace/v2/testtrace": {},
|
||||
"internal/trace/v2/version": {},
|
||||
"internal/txtar": {},
|
||||
"internal/types": {},
|
||||
"internal/types/errors": {},
|
||||
"internal/types/testdata": {},
|
||||
"internal/types/testdata/check": {},
|
||||
"internal/types/testdata/check/decls2": {},
|
||||
"internal/types/testdata/check/importdecl0": {},
|
||||
"internal/types/testdata/check/importdecl1": {},
|
||||
"internal/types/testdata/check/issue25008": {},
|
||||
"internal/types/testdata/examples": {},
|
||||
"internal/types/testdata/fixedbugs": {},
|
||||
"internal/types/testdata/spec": {},
|
||||
"internal/unsafeheader": {},
|
||||
"internal/xcoff": {},
|
||||
"internal/xcoff/testdata": {},
|
||||
"internal/zstd": {},
|
||||
"internal/zstd/testdata": {},
|
||||
"io": {},
|
||||
"io/fs": {},
|
||||
"io/ioutil": {},
|
||||
"io/ioutil/testdata": {},
|
||||
"iter": {},
|
||||
"log": {},
|
||||
"log/internal": {},
|
||||
"log/slog": {},
|
||||
"log/slog/internal": {},
|
||||
"log/slog/internal/benchmarks": {},
|
||||
"log/slog/internal/buffer": {},
|
||||
"log/slog/internal/slogtest": {},
|
||||
"log/syslog": {},
|
||||
"maps": {},
|
||||
"math": {},
|
||||
"math/big": {},
|
||||
"math/bits": {},
|
||||
"math/cmplx": {},
|
||||
"math/rand": {},
|
||||
"math/rand/v2": {},
|
||||
"mime": {},
|
||||
"mime/multipart": {},
|
||||
"mime/multipart/testdata": {},
|
||||
"mime/quotedprintable": {},
|
||||
"mime/testdata": {},
|
||||
"net": {},
|
||||
"net/http": {},
|
||||
"net/http/cgi": {},
|
||||
"net/http/cookiejar": {},
|
||||
"net/http/fcgi": {},
|
||||
"net/http/httptest": {},
|
||||
"net/http/httptrace": {},
|
||||
"net/http/httputil": {},
|
||||
"net/http/internal": {},
|
||||
"net/http/internal/ascii": {},
|
||||
"net/http/internal/testcert": {},
|
||||
"net/http/pprof": {},
|
||||
"net/http/pprof/testdata": {},
|
||||
"net/http/testdata": {},
|
||||
"net/internal": {},
|
||||
"net/internal/cgotest": {},
|
||||
"net/internal/socktest": {},
|
||||
"net/mail": {},
|
||||
"net/netip": {},
|
||||
"net/rpc": {},
|
||||
"net/rpc/jsonrpc": {},
|
||||
"net/smtp": {},
|
||||
"net/testdata": {},
|
||||
"net/textproto": {},
|
||||
"net/url": {},
|
||||
"os": {},
|
||||
"os/exec": {},
|
||||
"os/exec/internal": {},
|
||||
"os/exec/internal/fdtest": {},
|
||||
"os/signal": {},
|
||||
"os/testdata": {},
|
||||
"os/testdata/dirfs": {},
|
||||
"os/testdata/dirfs/dir": {},
|
||||
"os/testdata/issue37161": {},
|
||||
"os/user": {},
|
||||
"path": {},
|
||||
"path/filepath": {},
|
||||
"plugin": {},
|
||||
"reflect": {},
|
||||
"reflect/internal": {},
|
||||
"reflect/internal/example1": {},
|
||||
"reflect/internal/example2": {},
|
||||
"regexp": {},
|
||||
"regexp/syntax": {},
|
||||
"regexp/testdata": {},
|
||||
"runtime": {},
|
||||
"runtime/asan": {},
|
||||
"runtime/cgo": {},
|
||||
"runtime/coverage": {},
|
||||
"runtime/coverage/testdata": {},
|
||||
"runtime/coverage/testdata/issue56006": {},
|
||||
"runtime/coverage/testdata/issue59563": {},
|
||||
"runtime/debug": {},
|
||||
"runtime/debug/testdata": {},
|
||||
"runtime/debug/testdata/fuzz": {},
|
||||
"runtime/debug/testdata/fuzz/FuzzParseBuildInfoRoundTrip": {},
|
||||
"runtime/internal": {},
|
||||
"runtime/internal/atomic": {},
|
||||
"runtime/internal/math": {},
|
||||
"runtime/internal/startlinetest": {},
|
||||
"runtime/internal/sys": {},
|
||||
"runtime/internal/syscall": {},
|
||||
"runtime/internal/wasitest": {},
|
||||
"runtime/internal/wasitest/testdata": {},
|
||||
"runtime/metrics": {},
|
||||
"runtime/msan": {},
|
||||
"runtime/pprof": {},
|
||||
"runtime/pprof/testdata": {},
|
||||
"runtime/pprof/testdata/mappingtest": {},
|
||||
"runtime/race": {},
|
||||
"runtime/race/internal": {},
|
||||
"runtime/race/internal/amd64v1": {},
|
||||
"runtime/race/internal/amd64v3": {},
|
||||
"runtime/race/testdata": {},
|
||||
"runtime/testdata": {},
|
||||
"runtime/testdata/testexithooks": {},
|
||||
"runtime/testdata/testfaketime": {},
|
||||
"runtime/testdata/testfds": {},
|
||||
"runtime/testdata/testprog": {},
|
||||
"runtime/testdata/testprogcgo": {},
|
||||
"runtime/testdata/testprogcgo/windows": {},
|
||||
"runtime/testdata/testprognet": {},
|
||||
"runtime/testdata/testsuid": {},
|
||||
"runtime/testdata/testwinlib": {},
|
||||
"runtime/testdata/testwinlibsignal": {},
|
||||
"runtime/testdata/testwinlibthrow": {},
|
||||
"runtime/testdata/testwinsignal": {},
|
||||
"runtime/testdata/testwintls": {},
|
||||
"runtime/trace": {},
|
||||
"slices": {},
|
||||
"sort": {},
|
||||
"strconv": {},
|
||||
"strconv/testdata": {},
|
||||
"strings": {},
|
||||
"sync": {},
|
||||
"sync/atomic": {},
|
||||
"syscall": {},
|
||||
"syscall/js": {},
|
||||
"testdata": {},
|
||||
"testing": {},
|
||||
"testing/fstest": {},
|
||||
"testing/internal": {},
|
||||
"testing/internal/testdeps": {},
|
||||
"testing/iotest": {},
|
||||
"testing/quick": {},
|
||||
"testing/slogtest": {},
|
||||
"text": {},
|
||||
"text/scanner": {},
|
||||
"text/tabwriter": {},
|
||||
"text/template": {},
|
||||
"text/template/parse": {},
|
||||
"text/template/testdata": {},
|
||||
"time": {},
|
||||
"time/testdata": {},
|
||||
"time/tzdata": {},
|
||||
"unicode": {},
|
||||
"unicode/utf16": {},
|
||||
"unicode/utf8": {},
|
||||
"unsafe": {},
|
||||
"vendor": {},
|
||||
"vendor/golang.org": {},
|
||||
"vendor/golang.org/x": {},
|
||||
"vendor/golang.org/x/crypto": {},
|
||||
"vendor/golang.org/x/crypto/chacha20": {},
|
||||
"vendor/golang.org/x/crypto/chacha20poly1305": {},
|
||||
"vendor/golang.org/x/crypto/cryptobyte": {},
|
||||
"vendor/golang.org/x/crypto/cryptobyte/asn1": {},
|
||||
"vendor/golang.org/x/crypto/hkdf": {},
|
||||
"vendor/golang.org/x/crypto/internal": {},
|
||||
"vendor/golang.org/x/crypto/internal/alias": {},
|
||||
"vendor/golang.org/x/crypto/internal/poly1305": {},
|
||||
"vendor/golang.org/x/net": {},
|
||||
"vendor/golang.org/x/net/dns": {},
|
||||
"vendor/golang.org/x/net/dns/dnsmessage": {},
|
||||
"vendor/golang.org/x/net/http": {},
|
||||
"vendor/golang.org/x/net/http/httpguts": {},
|
||||
"vendor/golang.org/x/net/http/httpproxy": {},
|
||||
"vendor/golang.org/x/net/http2": {},
|
||||
"vendor/golang.org/x/net/http2/hpack": {},
|
||||
"vendor/golang.org/x/net/idna": {},
|
||||
"vendor/golang.org/x/net/lif": {},
|
||||
"vendor/golang.org/x/net/nettest": {},
|
||||
"vendor/golang.org/x/net/route": {},
|
||||
"vendor/golang.org/x/sys": {},
|
||||
"vendor/golang.org/x/sys/cpu": {},
|
||||
"vendor/golang.org/x/text": {},
|
||||
"vendor/golang.org/x/text/secure": {},
|
||||
"vendor/golang.org/x/text/secure/bidirule": {},
|
||||
"vendor/golang.org/x/text/transform": {},
|
||||
"vendor/golang.org/x/text/unicode": {},
|
||||
"vendor/golang.org/x/text/unicode/bidi": {},
|
||||
"vendor/golang.org/x/text/unicode/norm": {},
|
||||
}
|
826
vendor/github.com/go-delve/gore/type.go
generated
vendored
826
vendor/github.com/go-delve/gore/type.go
generated
vendored
@ -1,826 +0,0 @@
|
||||
// This file is part of GoRE.
|
||||
//
|
||||
// Copyright (C) 2019-2021 GoRE Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package gore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const (
|
||||
intSize32 = 4
|
||||
intSize64 = intSize32 * 2
|
||||
kindMask = (1 << 5) - 1
|
||||
tflagExtraStar uint8 = 1 << 1
|
||||
tflagUncommon uint8 = 1 << 0
|
||||
)
|
||||
|
||||
type _typeField uint8
|
||||
|
||||
const (
|
||||
_typeFieldSize = iota
|
||||
_typeFieldKind
|
||||
_typeFieldStr
|
||||
_typeFieldFlag
|
||||
_typeFieldEnd
|
||||
)
|
||||
|
||||
// ChanDir is a channel direction.
|
||||
type ChanDir int
|
||||
|
||||
const (
|
||||
// ChanRecv is a receive only chan (<-chan)
|
||||
ChanRecv ChanDir = 1 << iota
|
||||
// ChanSend is a send only chan (chan<-)
|
||||
ChanSend
|
||||
// ChanBoth is a send and receive chan (chan)
|
||||
ChanBoth = ChanRecv | ChanSend
|
||||
)
|
||||
|
||||
func getTypes(fileInfo *FileInfo, f fileHandler) (map[uint64]*GoType, error) {
|
||||
if GoVersionCompare(fileInfo.goversion.Name, "go1.7beta1") < 0 {
|
||||
return getLegacyTypes(fileInfo, f)
|
||||
}
|
||||
|
||||
md, err := parseModuledata(fileInfo, f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse the module data: %w", err)
|
||||
}
|
||||
|
||||
types, err := md.Types().Data()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get types data section: %w", err)
|
||||
}
|
||||
|
||||
typeLink, err := md.TypeLink()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get type link data: %w", err)
|
||||
}
|
||||
|
||||
// New parser
|
||||
parser := newTypeParser(types, md.Types().Address, fileInfo)
|
||||
for _, off := range typeLink {
|
||||
typ, err := parser.parseType(uint64(off) + parser.base)
|
||||
if err != nil || typ == nil {
|
||||
return nil, fmt.Errorf("failed to parse type at offset 0x%x: %w", off, err)
|
||||
}
|
||||
}
|
||||
return parser.parsedTypes(), nil
|
||||
}
|
||||
|
||||
func getLegacyTypes(fileInfo *FileInfo, f fileHandler) (map[uint64]*GoType, error) {
|
||||
md, err := parseModuledata(fileInfo, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typelinkAddr, typelinkData, err := f.getSectionDataFromOffset(md.TypelinkAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("no typelink section found: %w", err)
|
||||
}
|
||||
r := bytes.NewReader(typelinkData)
|
||||
_, err = r.Seek(int64(md.TypelinkAddr)-int64(typelinkAddr), io.SeekStart)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
goTypes := make(map[uint64]*GoType)
|
||||
for i := uint64(0); i < md.TypelinkLen; i++ {
|
||||
// Type offsets are always *_type
|
||||
off, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
baseAddr, baseData, err := f.getSectionDataFromOffset(off)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
typ := typeParse(goTypes, fileInfo, off-baseAddr, baseData, baseAddr)
|
||||
if typ == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return goTypes, nil
|
||||
}
|
||||
|
||||
// GoType is a representation of all types in Go.
|
||||
type GoType struct {
|
||||
// Kind indicates the specific kind of type the GoType
|
||||
Kind reflect.Kind
|
||||
// Name is the name of the type.
|
||||
Name string
|
||||
// Addr is the virtual address to where the type struct is defined.
|
||||
Addr uint64
|
||||
// PtrResolvAddr is the address to where the resolved structure is located
|
||||
// if the GoType is of pointer kind.
|
||||
PtrResolvAddr uint64
|
||||
// PackagePath is the name of the package import path for the GoType.
|
||||
PackagePath string
|
||||
// Fields is a slice of the struct fields if the GoType is of kind struct.
|
||||
Fields []*GoType
|
||||
// FieldName is the name of the field if the GoType is a struct field.
|
||||
FieldName string
|
||||
// FieldTag holds the extracted tag for the field.
|
||||
FieldTag string
|
||||
// FieldAnon is true if the field does not have a name and is an embedded type.
|
||||
FieldAnon bool
|
||||
// Element is the element type for arrays, slices channels or the resolved type for
|
||||
// a pointer type. For example int if the slice is a []int.
|
||||
Element *GoType
|
||||
// Length is the array or slice length.
|
||||
Length int
|
||||
// ChanDir is the channel direction
|
||||
ChanDir ChanDir
|
||||
// Key is the key type for a map.
|
||||
Key *GoType
|
||||
// FuncArgs holds the argument types for the function if the type is a function kind.
|
||||
FuncArgs []*GoType
|
||||
// FuncReturnVals holds the return types for the function if the type is a function kind.
|
||||
FuncReturnVals []*GoType
|
||||
// IsVariadic is true if the last argument type is variadic. For example "func(s string, n ...int)"
|
||||
IsVariadic bool
|
||||
// Methods holds information of the types methods.
|
||||
Methods []*TypeMethod
|
||||
flag uint8
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (t *GoType) String() string {
|
||||
switch t.Kind {
|
||||
case reflect.Slice:
|
||||
return fmt.Sprintf("[]%s", t.Element)
|
||||
case reflect.Array:
|
||||
return fmt.Sprintf("[%d]%s", t.Length, t.Element)
|
||||
case reflect.Map:
|
||||
return fmt.Sprintf("map[%s]%s", t.Key, t.Element)
|
||||
case reflect.Struct:
|
||||
// Handle empty struct type
|
||||
if t.Name == "" {
|
||||
return "struct{}"
|
||||
}
|
||||
return t.Name
|
||||
case reflect.Ptr:
|
||||
return fmt.Sprintf("*%s", t.Element)
|
||||
case reflect.Chan:
|
||||
if t.ChanDir == ChanRecv {
|
||||
return fmt.Sprintf("<-chan %s", t.Element)
|
||||
}
|
||||
if t.ChanDir == ChanSend {
|
||||
return fmt.Sprintf("chan<- %s", t.Element)
|
||||
}
|
||||
return fmt.Sprintf("chan %s", t.Element)
|
||||
case reflect.Func:
|
||||
buf := "func("
|
||||
for i, a := range t.FuncArgs {
|
||||
if i != 0 {
|
||||
buf += ", "
|
||||
}
|
||||
if a.Kind == reflect.Func && a.Name == t.Name {
|
||||
buf += a.Name
|
||||
} else {
|
||||
buf += a.String()
|
||||
}
|
||||
}
|
||||
if len(t.FuncReturnVals) > 1 {
|
||||
buf += ") ("
|
||||
} else if len(t.FuncReturnVals) == 1 {
|
||||
buf += ") "
|
||||
} else {
|
||||
buf += ")"
|
||||
}
|
||||
for i, r := range t.FuncReturnVals {
|
||||
if i != 0 {
|
||||
buf += ", "
|
||||
}
|
||||
if r.Kind == reflect.Func && r.Name == t.Name {
|
||||
buf += r.Name
|
||||
} else {
|
||||
buf += r.String()
|
||||
}
|
||||
}
|
||||
if len(t.FuncReturnVals) > 1 {
|
||||
buf += ")"
|
||||
}
|
||||
return buf
|
||||
case reflect.Interface:
|
||||
// Handle empty interface
|
||||
if t.Name == "" {
|
||||
return "interface{}"
|
||||
}
|
||||
return t.Name
|
||||
case reflect.Invalid:
|
||||
return t.Name
|
||||
default:
|
||||
return t.Kind.String()
|
||||
}
|
||||
}
|
||||
|
||||
// StructDef reconstructs the type definition code for the struct.
|
||||
// If the type is not a struct, an empty string is returned.
|
||||
func StructDef(typ *GoType) string {
|
||||
if typ.Kind != reflect.Struct {
|
||||
return ""
|
||||
}
|
||||
buf := fmt.Sprintf("type %s struct{", typ.Name)
|
||||
for _, f := range typ.Fields {
|
||||
if f.FieldAnon {
|
||||
buf += fmt.Sprintf("\n\t%s", f)
|
||||
} else {
|
||||
buf += fmt.Sprintf("\n\t%s %s", f.FieldName, f)
|
||||
}
|
||||
if f.FieldTag != "" {
|
||||
buf += "\t`" + f.FieldTag + "`"
|
||||
}
|
||||
}
|
||||
if len(typ.Fields) > 0 {
|
||||
buf += "\n"
|
||||
}
|
||||
return buf + "}"
|
||||
}
|
||||
|
||||
// InterfaceDef reconstructs the type definition code for the interface.
|
||||
// If the type is not an interface, an empty string is returned.
|
||||
func InterfaceDef(typ *GoType) string {
|
||||
if typ.Kind != reflect.Interface {
|
||||
return ""
|
||||
}
|
||||
// Handle interface with no methods defined.
|
||||
if len(typ.Methods) == 0 {
|
||||
return "type " + typ.Name + " interface{}"
|
||||
}
|
||||
// Remove package from name.
|
||||
buf := fmt.Sprintf("type %s interface {", typ.Name)
|
||||
for _, m := range typ.Methods {
|
||||
buf += fmt.Sprintf("\n\t%s%s", m.Name, m.Type.String()[4:])
|
||||
}
|
||||
return buf + "\n}"
|
||||
}
|
||||
|
||||
// MethodDef constructs a string summary of all methods for the type.
|
||||
// If type information exists for the methods, it is used to determine function parameters.
|
||||
// If the type does not have any methods, an empty string is returned.
|
||||
func MethodDef(typ *GoType) string {
|
||||
if len(typ.Methods) == 0 {
|
||||
return ""
|
||||
}
|
||||
var buf string
|
||||
for i, m := range typ.Methods {
|
||||
if i > 0 {
|
||||
buf += "\n"
|
||||
}
|
||||
if m.Type != nil {
|
||||
buf += fmt.Sprintf("func (%s) %s%s", typ.Name, m.Name, m.Type.String()[4:])
|
||||
} else {
|
||||
buf += fmt.Sprintf("func (%s) %s()", typ.Name, m.Name)
|
||||
}
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
// TypeMethod is description of a method owned by the GoType.
|
||||
type TypeMethod struct {
|
||||
// Name is the string name for the method.
|
||||
Name string
|
||||
// Type is the specific function type for the method.
|
||||
// This can be nil. If it is nil, the method is not part of an
|
||||
// implementation of a interface or it is not exported.
|
||||
Type *GoType
|
||||
// IfaceCallOffset is the offset from the beginning of the .text section
|
||||
// where the function code starts. According to code comments in the
|
||||
// standard library, it is used for interface calls.
|
||||
// Can be 0 if the code is not called in the binary and was optimized out
|
||||
// by the compiler or linker.
|
||||
IfaceCallOffset uint64
|
||||
// FuncCallOffset is the offset from the beginning of the .text section
|
||||
// where the function code starts. According to code comments in the
|
||||
// standard library, it is used for normal method calls.
|
||||
// Can be 0 if the code is not called in the binary and was optimized out
|
||||
// by the compiler or linker.
|
||||
FuncCallOffset uint64
|
||||
}
|
||||
|
||||
/*
|
||||
Size: 32 or 48
|
||||
type _type struct {
|
||||
size uintptr 4 or 8
|
||||
ptrdata uintptr 4 or 8
|
||||
hash uint32 4
|
||||
tflag tflag 1
|
||||
align uint8 1
|
||||
fieldalign uint8 1
|
||||
kind uint8 1
|
||||
alg *typeAlg 4 or 8
|
||||
gcdata *byte 4 or 8
|
||||
str nameOff 4
|
||||
ptrToThis typeOff 4
|
||||
}
|
||||
*/
|
||||
|
||||
func typeParse(types map[uint64]*GoType, fileInfo *FileInfo, offset uint64, sectionData []byte, sectionBaseAddr uint64) *GoType {
|
||||
typ, ok := types[offset+sectionBaseAddr]
|
||||
if ok {
|
||||
return typ
|
||||
}
|
||||
typ = new(GoType)
|
||||
// XXX: This is to catch bad parsing. The current parser does not handle
|
||||
// uncommon functions correctly. This ensures an out of bounds read does
|
||||
// not occur.
|
||||
if offset > uint64(len(sectionData)) {
|
||||
return nil
|
||||
}
|
||||
r := bytes.NewReader(sectionData[offset:])
|
||||
|
||||
// Parse size
|
||||
off := typeOffset(fileInfo, _typeFieldSize)
|
||||
r.Seek(off, io.SeekStart)
|
||||
_, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parse kind
|
||||
off = typeOffset(fileInfo, _typeFieldKind)
|
||||
// Defined as uint8
|
||||
var k uint8
|
||||
r.Seek(off, io.SeekStart)
|
||||
binary.Read(r, fileInfo.ByteOrder, &k)
|
||||
typ.Kind = reflect.Kind(k & kindMask)
|
||||
|
||||
// Parse flag
|
||||
off = typeOffset(fileInfo, _typeFieldFlag)
|
||||
// Defined as uint8
|
||||
var f uint8
|
||||
r.Seek(off, io.SeekStart)
|
||||
binary.Read(r, fileInfo.ByteOrder, &f)
|
||||
typ.flag = f
|
||||
|
||||
// Parse nameOff
|
||||
off = typeOffset(fileInfo, _typeFieldStr)
|
||||
r.Seek(off, io.SeekStart)
|
||||
ptrN, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if ptrN != 0 {
|
||||
typ.Name = parseString(fileInfo, ptrN, sectionBaseAddr, sectionData)
|
||||
}
|
||||
|
||||
typ.Addr = offset + sectionBaseAddr
|
||||
types[typ.Addr] = typ
|
||||
|
||||
// Legacy types has a field with a pointer to the uncommonType.
|
||||
// The flags location is unused, hence 0, so the parsing of the uncommonType
|
||||
// is skipped below. So instead, if the binary uses legacy types parse it now.
|
||||
// Pointer is right after the string pointer.
|
||||
off = typeOffset(fileInfo, _typeFieldStr) + int64(fileInfo.WordSize)
|
||||
r.Seek(off, io.SeekStart)
|
||||
ptr, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if ptr != 0 {
|
||||
// Since we don't know if the struct is located before or after this type,
|
||||
// create a new reader.
|
||||
ur := bytes.NewReader(sectionData)
|
||||
ur.Seek(int64(ptr-sectionBaseAddr), io.SeekStart)
|
||||
parseUncommonType(typ, ur, fileInfo, sectionData, sectionBaseAddr, types)
|
||||
}
|
||||
|
||||
// Parse extra fields
|
||||
off = typeOffset(fileInfo, _typeFieldEnd)
|
||||
r.Seek(off, io.SeekStart)
|
||||
switch typ.Kind {
|
||||
|
||||
case reflect.Ptr:
|
||||
ptr, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
typ.PtrResolvAddr = ptr
|
||||
if ptr != 0 {
|
||||
c := typeParse(types, fileInfo, ptr-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
typ.Element = c
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
|
||||
// Parse struct fields
|
||||
fieldptr, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
numfield, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
// Eat cap
|
||||
_, err = readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parse methods
|
||||
if typ.flag&tflagUncommon != 0 {
|
||||
parseUncommonType(typ, r, fileInfo, sectionData, sectionBaseAddr, types)
|
||||
}
|
||||
|
||||
// Parse fields
|
||||
typ.Fields = make([]*GoType, numfield)
|
||||
secR := bytes.NewReader(sectionData)
|
||||
for i := 0; i < int(numfield); i++ {
|
||||
var fieldName string
|
||||
var tag string
|
||||
o := int64(fieldptr + uint64(i*5*fileInfo.WordSize) - sectionBaseAddr)
|
||||
secR.Seek(o, io.SeekStart)
|
||||
nptr, err := readUIntTo64(secR, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
ppp, err := readUIntTo64(secR, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if ppp != 0 {
|
||||
pps := parseString(fileInfo, ppp, sectionBaseAddr, sectionData)
|
||||
if pps != "" {
|
||||
typ.PackagePath = pps
|
||||
}
|
||||
}
|
||||
tptr, err := readUIntTo64(secR, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
tagptr, err := readUIntTo64(secR, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if tagptr != 0 {
|
||||
tag = parseString(fileInfo, tagptr, sectionBaseAddr, sectionData)
|
||||
}
|
||||
uptr, err := readUIntTo64(secR, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
gt := typeParse(types, fileInfo, tptr-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
// Make a copy
|
||||
field := *gt
|
||||
|
||||
fieldName = parseString(fileInfo, nptr, sectionBaseAddr, sectionData)
|
||||
field.FieldName = fieldName
|
||||
if tag != "" {
|
||||
field.FieldTag = tag
|
||||
}
|
||||
// Older versions has no field name for anonymous fields. New versions
|
||||
// uses a bit flag on the offset.
|
||||
field.FieldAnon = fieldName == "" || uptr&1 != 0
|
||||
typ.Fields[i] = &field
|
||||
}
|
||||
case reflect.Array:
|
||||
|
||||
elementAddr, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if elementAddr != 0 {
|
||||
e := typeParse(types, fileInfo, elementAddr-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
typ.Element = e
|
||||
}
|
||||
|
||||
// Read and skip slice type
|
||||
_, err = readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read length
|
||||
l, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
typ.Length = int(l)
|
||||
|
||||
case reflect.Slice:
|
||||
|
||||
elementAddr, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if elementAddr != 0 {
|
||||
e := typeParse(types, fileInfo, elementAddr-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
typ.Element = e
|
||||
}
|
||||
|
||||
case reflect.Chan:
|
||||
|
||||
elementAddr, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if elementAddr != 0 {
|
||||
e := typeParse(types, fileInfo, elementAddr-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
typ.Element = e
|
||||
}
|
||||
|
||||
// Direction
|
||||
d, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
typ.ChanDir = ChanDir(int(d))
|
||||
|
||||
case reflect.Map:
|
||||
|
||||
keyAddr, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if keyAddr != 0 {
|
||||
k := typeParse(types, fileInfo, keyAddr-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
typ.Key = k
|
||||
}
|
||||
|
||||
elementAddr, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if elementAddr != 0 {
|
||||
e := typeParse(types, fileInfo, elementAddr-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
typ.Element = e
|
||||
}
|
||||
|
||||
case reflect.Func:
|
||||
|
||||
// bool plus padding.
|
||||
dotdotdot, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
typ.IsVariadic = dotdotdot > uint64(0)
|
||||
// One for args and one for returns
|
||||
rtypes := make([]uint64, 2)
|
||||
typelens := make([]uint64, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
p, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
rtypes[i] = p
|
||||
l, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
typelens[i] = l
|
||||
|
||||
// Eat cap
|
||||
_, err = readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
println("Error when reading padding:", err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// Full section reader
|
||||
sr := bytes.NewReader(sectionData)
|
||||
// Parse the arg types and result types.
|
||||
for i := 0; i < 2; i++ {
|
||||
if rtypes[i] == 0 {
|
||||
continue
|
||||
}
|
||||
_, err = sr.Seek(int64(rtypes[i]-sectionBaseAddr), io.SeekStart)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for j := 0; j < int(typelens[i]); j++ {
|
||||
p, err := readUIntTo64(sr, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if p == 0 {
|
||||
continue
|
||||
}
|
||||
t := typeParse(types, fileInfo, p-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
if i == 0 {
|
||||
typ.FuncArgs = append(typ.FuncArgs, t)
|
||||
} else {
|
||||
typ.FuncReturnVals = append(typ.FuncReturnVals, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Interface:
|
||||
|
||||
ptrMethods, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
numMethods, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
// Eat cap
|
||||
_, err = readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parse imethods
|
||||
secR := bytes.NewReader(sectionData)
|
||||
imethSize := uint64(2 * intSize32)
|
||||
int32ptr := true
|
||||
if GoVersionCompare(fileInfo.goversion.Name, "go1.7beta1") < 0 {
|
||||
imethSize = uint64(3 * fileInfo.WordSize)
|
||||
int32ptr = fileInfo.WordSize == intSize32
|
||||
}
|
||||
for i := 0; i < int(numMethods); i++ {
|
||||
meth := new(TypeMethod)
|
||||
// All fields has the size of int32
|
||||
secR.Seek(int64(ptrMethods+uint64(i)*imethSize-sectionBaseAddr), io.SeekStart)
|
||||
nameOff, err := readUIntTo64(secR, fileInfo.ByteOrder, int32ptr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if nameOff != 0 {
|
||||
meth.Name = parseString(fileInfo, nameOff, sectionBaseAddr, sectionData)
|
||||
}
|
||||
|
||||
pkgPathPtr, err := readUIntTo64(secR, fileInfo.ByteOrder, int32ptr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if pkgPathPtr != 0 {
|
||||
pkgPathStr := parseString(fileInfo, pkgPathPtr, sectionBaseAddr, sectionData)
|
||||
if pkgPathStr != "" {
|
||||
typ.PackagePath = pkgPathStr
|
||||
}
|
||||
}
|
||||
|
||||
typeOff, err := readUIntTo64(secR, fileInfo.ByteOrder, int32ptr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if typeOff != 0 {
|
||||
typeOff = typeOff - sectionBaseAddr
|
||||
meth.Type = typeParse(types, fileInfo, typeOff, sectionData, sectionBaseAddr)
|
||||
}
|
||||
typ.Methods = append(typ.Methods, meth)
|
||||
}
|
||||
}
|
||||
return typ
|
||||
}
|
||||
|
||||
func parseString(fileInfo *FileInfo, off, base uint64, baseData []byte) string {
|
||||
if off == 0 {
|
||||
return ""
|
||||
}
|
||||
r := bytes.NewReader(baseData)
|
||||
r.Seek(int64(off-base), io.SeekStart)
|
||||
h, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
l, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if h == 0 || l == 0 {
|
||||
return ""
|
||||
}
|
||||
str := string(baseData[h-base : h-base+l])
|
||||
return str
|
||||
}
|
||||
|
||||
func parseUncommonType(typ *GoType, r *bytes.Reader, fileInfo *FileInfo, sectionData []byte, sectionBaseAddr uint64, types map[uint64]*GoType) {
|
||||
pname, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if pname != 0 {
|
||||
n := parseString(fileInfo, pname, sectionBaseAddr, sectionData)
|
||||
if typ.Name == "" && n != "" {
|
||||
typ.Name = n
|
||||
}
|
||||
}
|
||||
ppkg, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if ppkg != 0 {
|
||||
p := parseString(fileInfo, ppkg, sectionBaseAddr, sectionData)
|
||||
if typ.PackagePath == "" && p != "" {
|
||||
typ.PackagePath = p
|
||||
}
|
||||
}
|
||||
typ.Methods = parseMethods(r, fileInfo, sectionData, sectionBaseAddr, types)
|
||||
}
|
||||
|
||||
// The methods must start at the readers current location.
|
||||
func parseMethods(r *bytes.Reader, fileInfo *FileInfo, sectionData []byte, sectionBaseAddr uint64, types map[uint64]*GoType) []*TypeMethod {
|
||||
pdata, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
numMeth, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
methods := make([]*TypeMethod, numMeth)
|
||||
r.Seek(int64(pdata-sectionBaseAddr), io.SeekStart)
|
||||
for i := 0; i < int(numMeth); i++ {
|
||||
m := &TypeMethod{}
|
||||
p, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
m.Name = parseString(fileInfo, p, sectionBaseAddr, sectionData)
|
||||
|
||||
// Eat package path
|
||||
_, err = readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// mtyp
|
||||
mtype, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if mtype != 0 {
|
||||
m.Type = typeParse(types, fileInfo, mtype-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
}
|
||||
|
||||
// typ
|
||||
p, err = readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if p != 0 {
|
||||
// Parse it so we capture it in the global type list.
|
||||
typeParse(types, fileInfo, p-sectionBaseAddr, sectionData, sectionBaseAddr)
|
||||
}
|
||||
|
||||
// ifn
|
||||
ifn, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
m.IfaceCallOffset = ifn
|
||||
|
||||
// tfn
|
||||
tfn, err := readUIntTo64(r, fileInfo.ByteOrder, fileInfo.WordSize == intSize32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
m.FuncCallOffset = tfn
|
||||
methods[i] = m
|
||||
}
|
||||
return methods
|
||||
}
|
||||
|
||||
func typeOffset(fileInfo *FileInfo, field _typeField) int64 {
|
||||
intSize := intSize64
|
||||
if fileInfo.WordSize == intSize32 {
|
||||
intSize = intSize32
|
||||
}
|
||||
if field == _typeFieldSize {
|
||||
return int64(0)
|
||||
}
|
||||
|
||||
if field == _typeFieldKind {
|
||||
return int64(2*intSize + 4 + 3)
|
||||
}
|
||||
|
||||
if field == _typeFieldStr {
|
||||
return int64(4*intSize + 4 + 4)
|
||||
}
|
||||
|
||||
if field == _typeFieldFlag {
|
||||
return int64(2*intSize + 4)
|
||||
}
|
||||
|
||||
if field == _typeFieldEnd {
|
||||
if GoVersionCompare(fileInfo.goversion.Name, "go1.6beta1") < 0 {
|
||||
return int64(8*intSize + 8)
|
||||
}
|
||||
if GoVersionCompare(fileInfo.goversion.Name, "go1.7beta1") < 0 {
|
||||
return int64(7*intSize + 8)
|
||||
}
|
||||
return int64(4*intSize + 16)
|
||||
}
|
||||
return int64(-1)
|
||||
}
|
1248
vendor/github.com/go-delve/gore/type2.go
generated
vendored
1248
vendor/github.com/go-delve/gore/type2.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5
vendor/modules.txt
vendored
5
vendor/modules.txt
vendored
@ -24,9 +24,6 @@ github.com/creack/pty
|
||||
# github.com/derekparker/trie v0.0.0-20230829180723-39f4de51ef7d
|
||||
## explicit; go 1.19
|
||||
github.com/derekparker/trie
|
||||
# github.com/go-delve/gore v0.11.8
|
||||
## explicit; go 1.21
|
||||
github.com/go-delve/gore
|
||||
# github.com/go-delve/liner v1.2.3-0.20231231155935-4726ab1d7f62
|
||||
## explicit
|
||||
github.com/go-delve/liner
|
||||
@ -64,6 +61,8 @@ github.com/spf13/cobra/doc
|
||||
# github.com/spf13/pflag v1.0.5
|
||||
## explicit; go 1.12
|
||||
github.com/spf13/pflag
|
||||
# github.com/stretchr/testify v1.8.4
|
||||
## explicit; go 1.20
|
||||
# go.starlark.net v0.0.0-20231101134539-556fd59b42f6
|
||||
## explicit; go 1.18
|
||||
go.starlark.net/internal/compile
|
||||
|
Loading…
Reference in New Issue
Block a user