diff options
| author | Cuong Manh Le <cuong.manhle.vn@gmail.com> | 2021-05-08 00:45:06 +0700 |
|---|---|---|
| committer | Cuong Manh Le <cuong.manhle.vn@gmail.com> | 2022-08-09 11:28:56 +0000 |
| commit | 0f8dffd0aa71ed996d32e77701ac5ec0bc7cde01 (patch) | |
| tree | 9840e8c7e2abac7674a9dfaa6b0c73655124f0fa /src/debug | |
| parent | 5639fcae7fee2cf04c1b87e9a81155ee3bb6ed71 (diff) | |
| download | go-0f8dffd0aa71ed996d32e77701ac5ec0bc7cde01.tar.xz | |
all: use ":" for compiler generated symbols
As it can't appear in user package paths.
There is a hack for handling "go:buildid" and "type:*" on windows/386.
Previously, windows/386 requires underscore prefix on external symbols,
but that's only applied for SHOSTOBJ/SUNDEFEXT or cgo export symbols.
"go.buildid" is STEXT, "type.*" is STYPE, thus they are not prefixed
with underscore.
In external linking mode, the external linker can't resolve them as
external symbols. But we are lucky that they have "." in their name,
so the external linker see them as Forwarder RVA exports. See:
- https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#export-address-table
- https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/pe-dll.c;h=e7b82ba6ffadf74dc1b9ee71dc13d48336941e51;hb=HEAD#l972)
This CL changes "." to ":" in symbols name, so theses symbols can not be
found by external linker anymore. So a hacky way is adding the
underscore prefix for these 2 symbols. I don't have enough knowledge to
verify whether adding the underscore for all STEXT/STYPE symbols are
fine, even if it could be, that would be done in future CL.
Fixes #37762
Change-Id: I92eaaf24c0820926a36e0530fdb07b07af1fcc35
Reviewed-on: https://go-review.googlesource.com/c/go/+/317917
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/debug')
| -rw-r--r-- | src/debug/gosym/pclntab.go | 12 | ||||
| -rw-r--r-- | src/debug/gosym/symtab.go | 16 | ||||
| -rw-r--r-- | src/debug/gosym/symtab_test.go | 28 |
3 files changed, 41 insertions, 15 deletions
diff --git a/src/debug/gosym/pclntab.go b/src/debug/gosym/pclntab.go index 2ceea3d46f..1aed5ed7e7 100644 --- a/src/debug/gosym/pclntab.go +++ b/src/debug/gosym/pclntab.go @@ -24,6 +24,7 @@ const ( ver12 ver116 ver118 + ver120 ) // A LineTable is a data structure mapping program counters to line numbers. @@ -173,6 +174,7 @@ const ( go12magic = 0xfffffffb go116magic = 0xfffffffa go118magic = 0xfffffff0 + go120magic = 0xfffffff1 ) // uintptr returns the pointer-sized value encoded at b. @@ -229,6 +231,10 @@ func (t *LineTable) parsePclnTab() { t.binary, possibleVersion = binary.LittleEndian, ver118 case beMagic == go118magic: t.binary, possibleVersion = binary.BigEndian, ver118 + case leMagic == go120magic: + t.binary, possibleVersion = binary.LittleEndian, ver120 + case beMagic == go120magic: + t.binary, possibleVersion = binary.BigEndian, ver120 default: return } @@ -246,7 +252,7 @@ func (t *LineTable) parsePclnTab() { } switch possibleVersion { - case ver118: + case ver118, ver120: t.nfunctab = uint32(offset(0)) t.nfiletab = uint32(offset(1)) t.textStart = t.PC // use the start PC instead of reading from the table, which may be unrelocated @@ -527,7 +533,7 @@ func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, fileStartPC := filePC for t.step(&fp, &filePC, &fileVal, filePC == entry) { fileIndex := fileVal - if t.version == ver116 || t.version == ver118 { + if t.version == ver116 || t.version == ver118 || t.version == ver120 { fileIndex = int32(t.binary.Uint32(cutab[fileVal*4:])) } if fileIndex == filenum && fileStartPC < filePC { @@ -626,7 +632,7 @@ func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) { entry := f.entryPC() filetab := f.pcfile() linetab := f.pcln() - if t.version == ver116 || t.version == ver118 { + if t.version == ver116 || t.version == ver118 || t.version == ver120 { if f.cuOffset() == ^uint32(0) { // skip functions without compilation unit (not real function, or linker generated) continue diff --git a/src/debug/gosym/symtab.go b/src/debug/gosym/symtab.go index afc67198c3..d87b312b56 100644 --- a/src/debug/gosym/symtab.go +++ b/src/debug/gosym/symtab.go @@ -27,6 +27,8 @@ type Sym struct { GoType uint64 // If this symbol is a function symbol, the corresponding Func Func *Func + + goVersion version } // Static reports whether this symbol is static (not visible outside its file). @@ -55,9 +57,16 @@ func (s *Sym) nameWithoutInst() string { func (s *Sym) PackageName() string { name := s.nameWithoutInst() - // A prefix of "type." and "go." is a compiler-generated symbol that doesn't belong to any package. - // See variable reservedimports in cmd/compile/internal/gc/subr.go - if strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.") { + // Since go1.20, a prefix of "type:" and "go:" is a compiler-generated symbol, + // they do not belong to any package. + // + // See cmd/compile/internal/base/link.go:ReservedImports variable. + if s.goVersion >= ver120 && (strings.HasPrefix(name, "go:") || strings.HasPrefix(name, "type:")) { + return "" + } + + // For go1.18 and below, the prefix are "type." and "go." instead. + if s.goVersion <= ver118 && (strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.")) { return "" } @@ -350,6 +359,7 @@ func NewTable(symtab []byte, pcln *LineTable) (*Table, error) { ts.Type = s.typ ts.Value = s.value ts.GoType = s.gotype + ts.goVersion = pcln.version switch s.typ { default: // rewrite name to use . instead of ยท (c2 b7) diff --git a/src/debug/gosym/symtab_test.go b/src/debug/gosym/symtab_test.go index da3c21209d..bb1f267a4d 100644 --- a/src/debug/gosym/symtab_test.go +++ b/src/debug/gosym/symtab_test.go @@ -62,16 +62,26 @@ func TestRemotePackage(t *testing.T) { } func TestIssue29551(t *testing.T) { - symNames := []string{ - "type..eq.[9]debug/elf.intName", - "type..hash.debug/elf.ProgHeader", - "type..eq.runtime._panic", - "type..hash.struct { runtime.gList; runtime.n int32 }", - "go.(*struct { sync.Mutex; math/big.table [64]math/big", + tests := []struct { + sym Sym + pkgName string + }{ + {Sym{goVersion: ver120, Name: "type:.eq.[9]debug/elf.intName"}, ""}, + {Sym{goVersion: ver120, Name: "type:.hash.debug/elf.ProgHeader"}, ""}, + {Sym{goVersion: ver120, Name: "type:.eq.runtime._panic"}, ""}, + {Sym{goVersion: ver120, Name: "type:.hash.struct { runtime.gList; runtime.n int32 }"}, ""}, + {Sym{goVersion: ver120, Name: "go:(*struct { sync.Mutex; math/big.table [64]math/big"}, ""}, + {Sym{goVersion: ver120, Name: "go.uber.org/zap/buffer.(*Buffer).AppendString"}, "go.uber.org/zap/buffer"}, + {Sym{goVersion: ver118, Name: "type..eq.[9]debug/elf.intName"}, ""}, + {Sym{goVersion: ver118, Name: "type..hash.debug/elf.ProgHeader"}, ""}, + {Sym{goVersion: ver118, Name: "type..eq.runtime._panic"}, ""}, + {Sym{goVersion: ver118, Name: "type..hash.struct { runtime.gList; runtime.n int32 }"}, ""}, + {Sym{goVersion: ver118, Name: "go.(*struct { sync.Mutex; math/big.table [64]math/big"}, ""}, + // unfortunate + {Sym{goVersion: ver118, Name: "go.uber.org/zap/buffer.(*Buffer).AppendString"}, ""}, } - for _, symName := range symNames { - s := Sym{Name: symName} - assertString(t, fmt.Sprintf("package of %q", s.Name), s.PackageName(), "") + for _, tc := range tests { + assertString(t, fmt.Sprintf("package of %q", tc.sym.Name), tc.sym.PackageName(), tc.pkgName) } } |
