]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/objfile, debug/gosym: use the address of runtime.text as textStart
authorCherry Mui <cherryyz@google.com>
Tue, 23 Nov 2021 23:03:47 +0000 (18:03 -0500)
committerCherry Mui <cherryyz@google.com>
Wed, 24 Nov 2021 16:01:55 +0000 (16:01 +0000)
Tools like objdump uses the pcln table to find the line number of
a given PC. For a PIE binary, at least in some cases such as on
macOS 12 with ld64-711, the table contains unrelocated address,
which does not match the address in the symbol table, causing the
lookup to fail.

In Go 1.18 the pcln table is essentually position independent,
except the start PC. Instead of reading the static content from
the table, use the PC of runtime.text from the symbol table.

While here, change the type of textStart to uint64. What matters
here is the word size of the target program, not the host, so it
shouldn't be uintptr.

Fixes #49700.

Change-Id: I517d79be7ba02dd4dd0275e75a11a136b08d76cd
Reviewed-on: https://go-review.googlesource.com/c/go/+/366695
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/internal/objfile/objfile.go
src/debug/gosym/pclntab.go

index dcfd158ec209274891640b0cd74fc35611fb0026..d890a0b7562cf4177afc03df877d271a0b499ad3 100644 (file)
@@ -152,6 +152,15 @@ func (e *Entry) PCLineTable() (Liner, error) {
        if err != nil {
                return nil, err
        }
+       syms, err := e.raw.symbols()
+       if err == nil {
+               for _, s := range syms {
+                       if s.Name == "runtime.text" {
+                               textStart = s.Addr
+                               break
+                       }
+               }
+       }
        return gosym.NewTable(symtab, gosym.NewLineTable(pclntab, textStart))
 }
 
index a687c406b2af83fd6735887dcb3e5c9fc045a649..d9ae8b73a93bc89cd722a076cd7a5cd6372dc24b 100644 (file)
@@ -54,7 +54,7 @@ type LineTable struct {
        binary      binary.ByteOrder
        quantum     uint32
        ptrsize     uint32
-       textStart   uintptr // address of runtime.text symbol (1.18+)
+       textStart   uint64 // address of runtime.text symbol (1.18+)
        funcnametab []byte
        cutab       []byte
        funcdata    []byte
@@ -249,7 +249,7 @@ func (t *LineTable) parsePclnTab() {
        case ver118:
                t.nfunctab = uint32(offset(0))
                t.nfiletab = uint32(offset(1))
-               t.textStart = uintptr(offset(2))
+               t.textStart = t.PC // use the start PC instead of reading from the table, which may be unrelocated
                t.funcnametab = data(3)
                t.cutab = data(4)
                t.filetab = data(5)
@@ -402,7 +402,7 @@ func (f funcTab) Count() int {
 func (f funcTab) pc(i int) uint64 {
        u := f.uint(f.functab[2*i*f.sz:])
        if f.version >= ver118 {
-               u += uint64(f.textStart)
+               u += f.textStart
        }
        return u
 }
@@ -444,7 +444,7 @@ func (f *funcData) entryPC() uint64 {
        if f.t.version >= ver118 {
                // TODO: support multiple text sections.
                // See runtime/symtab.go:(*moduledata).textAddr.
-               return uint64(f.t.binary.Uint32(f.data)) + uint64(f.t.textStart)
+               return uint64(f.t.binary.Uint32(f.data)) + f.t.textStart
        }
        return f.t.uintptr(f.data)
 }