mirror of
https://github.com/golang/go
synced 2024-11-24 02:10:11 -07:00
debug/goobj: expand package prefix correctly
R=r, bradfitz CC=golang-dev https://golang.org/cl/43480049
This commit is contained in:
parent
674606503e
commit
2404b7f168
@ -3614,7 +3614,8 @@ ngotype(Node *n)
|
||||
* only in the last segment of the path, and it makes for happier
|
||||
* users if we escape that as little as possible.
|
||||
*
|
||||
* If you edit this, edit ../ld/lib.c:/^pathtoprefix copy too.
|
||||
* If you edit this, edit ../ld/lib.c:/^pathtoprefix too.
|
||||
* If you edit this, edit ../../pkg/debug/goobj/read.go:/importPathToPrefix too.
|
||||
*/
|
||||
static char*
|
||||
pathtoprefix(char *s)
|
||||
|
@ -851,7 +851,8 @@ unmal(void *v, uint32 n)
|
||||
* Invalid bytes turn into %xx. Right now the only bytes that need
|
||||
* escaping are %, ., and ", but we escape all control characters too.
|
||||
*
|
||||
* Must be same as ../gc/subr.c:/^pathtoprefix.
|
||||
* If you edit this, edit ../gc/subr.c:/^pathtoprefix too.
|
||||
* If you edit this, edit ../../pkg/debug/goobj/read.go:/importPathToPrefix too.
|
||||
*/
|
||||
static char*
|
||||
pathtoprefix(char *s)
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A SymKind describes the kind of memory represented by a symbol.
|
||||
@ -180,14 +181,54 @@ var (
|
||||
|
||||
// An objReader is an object file reader.
|
||||
type objReader struct {
|
||||
p *Package
|
||||
b *bufio.Reader
|
||||
f io.ReadSeeker
|
||||
err error
|
||||
offset int64
|
||||
limit int64
|
||||
tmp [256]byte
|
||||
pkg string
|
||||
p *Package
|
||||
b *bufio.Reader
|
||||
f io.ReadSeeker
|
||||
err error
|
||||
offset int64
|
||||
limit int64
|
||||
tmp [256]byte
|
||||
pkg string
|
||||
pkgprefix string
|
||||
}
|
||||
|
||||
// importPathToPrefix returns the prefix that will be used in the
|
||||
// final symbol table for the given import path.
|
||||
// We escape '%', '"', all control characters and non-ASCII bytes,
|
||||
// and any '.' after the final slash.
|
||||
//
|
||||
// See ../../../cmd/ld/lib.c:/^pathtoprefix and
|
||||
// ../../../cmd/gc/subr.c:/^pathtoprefix.
|
||||
func importPathToPrefix(s string) string {
|
||||
// find index of last slash, if any, or else -1.
|
||||
// used for determining whether an index is after the last slash.
|
||||
slash := strings.LastIndex(s, "/")
|
||||
|
||||
// check for chars that need escaping
|
||||
n := 0
|
||||
for r := 0; r < len(s); r++ {
|
||||
if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
|
||||
n++
|
||||
}
|
||||
}
|
||||
|
||||
// quick exit
|
||||
if n == 0 {
|
||||
return s
|
||||
}
|
||||
|
||||
// escape
|
||||
const hex = "0123456789abcdef"
|
||||
p := make([]byte, 0, len(s)+2*n)
|
||||
for r := 0; r < len(s); r++ {
|
||||
if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
|
||||
p = append(p, '%', hex[c>>4], hex[c&0xF])
|
||||
} else {
|
||||
p = append(p, c)
|
||||
}
|
||||
}
|
||||
|
||||
return string(p)
|
||||
}
|
||||
|
||||
// init initializes r to read package p from f.
|
||||
@ -198,6 +239,7 @@ func (r *objReader) init(f io.ReadSeeker, p *Package) {
|
||||
r.limit, _ = f.Seek(0, 2)
|
||||
f.Seek(r.offset, 0)
|
||||
r.b = bufio.NewReader(f)
|
||||
r.pkgprefix = importPathToPrefix(p.ImportPath) + "."
|
||||
}
|
||||
|
||||
// error records that an error occurred.
|
||||
@ -296,6 +338,11 @@ func (r *objReader) readString() string {
|
||||
func (r *objReader) readSymID() SymID {
|
||||
name, vers := r.readString(), r.readInt()
|
||||
|
||||
// In a symbol name in an object file, "". denotes the
|
||||
// prefix for the package in which the object file has been found.
|
||||
// Expand it.
|
||||
name = strings.Replace(name, `"".`, r.pkgprefix, -1)
|
||||
|
||||
// An individual object file only records version 0 (extern) or 1 (static).
|
||||
// To make static symbols unique across all files being read, we
|
||||
// replace version 1 with the version corresponding to the current
|
||||
@ -346,6 +393,9 @@ func (r *objReader) skip(n int64) {
|
||||
// Parse parses an object file or archive from r,
|
||||
// assuming that its import path is pkgpath.
|
||||
func Parse(r io.ReadSeeker, pkgpath string) (*Package, error) {
|
||||
if pkgpath == "" {
|
||||
pkgpath = `""`
|
||||
}
|
||||
p := new(Package)
|
||||
p.ImportPath = pkgpath
|
||||
|
||||
|
28
src/pkg/debug/goobj/read_test.go
Normal file
28
src/pkg/debug/goobj/read_test.go
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package goobj
|
||||
|
||||
import "testing"
|
||||
|
||||
var importPathToPrefixTests = []struct {
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
{"runtime", "runtime"},
|
||||
{"sync/atomic", "sync/atomic"},
|
||||
{"code.google.com/p/go.tools/godoc", "code.google.com/p/go.tools/godoc"},
|
||||
{"foo.bar/baz.quux", "foo.bar/baz%2equux"},
|
||||
{"", ""},
|
||||
{"%foo%bar", "%25foo%25bar"},
|
||||
{"\x01\x00\x7F☺", "%01%00%7f%e2%98%ba"},
|
||||
}
|
||||
|
||||
func TestImportPathToPrefix(t *testing.T) {
|
||||
for _, tt := range importPathToPrefixTests {
|
||||
if out := importPathToPrefix(tt.in); out != tt.out {
|
||||
t.Errorf("importPathToPrefix(%q) = %q, want %q", tt.in, out, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user