mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: restore -strictdups flag in newobj mode
Change-Id: I93ad769595fa343400afa342af12e1445abff084 Reviewed-on: https://go-review.googlesource.com/c/go/+/204918 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
ab4a71fca7
commit
db75205a9b
3 changed files with 147 additions and 14 deletions
|
|
@ -119,9 +119,18 @@ type Loader struct {
|
|||
Reachparent []Sym
|
||||
|
||||
relocBatch []sym.Reloc // for bulk allocation of relocations
|
||||
|
||||
flags uint32
|
||||
|
||||
strictDupMsgs int // number of strict-dup warning/errors, when FlagStrictDups is enabled
|
||||
}
|
||||
|
||||
func NewLoader() *Loader {
|
||||
const (
|
||||
// Loader.flags
|
||||
FlagStrictDups = 1 << iota
|
||||
)
|
||||
|
||||
func NewLoader(flags uint32) *Loader {
|
||||
nbuiltin := goobj2.NBuiltin()
|
||||
return &Loader{
|
||||
start: make(map[*oReader]Sym),
|
||||
|
|
@ -132,6 +141,7 @@ func NewLoader() *Loader {
|
|||
itablink: make(map[Sym]struct{}),
|
||||
extStaticSyms: make(map[nameVer]Sym),
|
||||
builtinSyms: make([]Sym, nbuiltin),
|
||||
flags: flags,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +180,9 @@ func (l *Loader) AddSym(name string, ver int, i Sym, r *oReader, dupok bool, typ
|
|||
}
|
||||
if oldi, ok := l.symsByName[ver][name]; ok {
|
||||
if dupok {
|
||||
if l.flags&FlagStrictDups != 0 {
|
||||
l.checkdup(name, i, r, oldi)
|
||||
}
|
||||
return false
|
||||
}
|
||||
oldr, li := l.toLocal(oldi)
|
||||
|
|
@ -366,6 +379,42 @@ func (l *Loader) IsDup(i Sym) bool {
|
|||
return l.symsByName[ver][name] != i
|
||||
}
|
||||
|
||||
// Check that duplicate symbols have same contents.
|
||||
func (l *Loader) checkdup(name string, i Sym, r *oReader, dup Sym) {
|
||||
li := int(i - l.startIndex(r))
|
||||
p := r.Data(li)
|
||||
if strings.HasPrefix(name, "go.info.") {
|
||||
p, _ = patchDWARFName1(p, r)
|
||||
}
|
||||
rdup, ldup := l.toLocal(dup)
|
||||
pdup := rdup.Data(ldup)
|
||||
if strings.HasPrefix(name, "go.info.") {
|
||||
pdup, _ = patchDWARFName1(pdup, rdup)
|
||||
}
|
||||
if bytes.Equal(p, pdup) {
|
||||
return
|
||||
}
|
||||
reason := "same length but different contents"
|
||||
if len(p) != len(pdup) {
|
||||
reason = fmt.Sprintf("new length %d != old length %d", len(p), len(pdup))
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "cmd/link: while reading object for '%v': duplicate symbol '%s', previous def at '%v', with mismatched payload: %s\n", r.unit.Lib, name, rdup.unit.Lib, reason)
|
||||
|
||||
// For the moment, whitelist DWARF subprogram DIEs for
|
||||
// auto-generated wrapper functions. What seems to happen
|
||||
// here is that we get different line numbers on formal
|
||||
// params; I am guessing that the pos is being inherited
|
||||
// from the spot where the wrapper is needed.
|
||||
whitelist := strings.HasPrefix(name, "go.info.go.interface") ||
|
||||
strings.HasPrefix(name, "go.info.go.builtin") ||
|
||||
strings.HasPrefix(name, "go.debuglines")
|
||||
if !whitelist {
|
||||
l.strictDupMsgs++
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Loader) NStrictDupMsgs() int { return l.strictDupMsgs }
|
||||
|
||||
// Number of total symbols.
|
||||
func (l *Loader) NSym() int {
|
||||
return int(l.max + 1)
|
||||
|
|
@ -1194,24 +1243,30 @@ func loadObjFull(l *Loader, r *oReader) {
|
|||
|
||||
var emptyPkg = []byte(`"".`)
|
||||
|
||||
func patchDWARFName(s *sym.Symbol, r *oReader) {
|
||||
func patchDWARFName1(p []byte, r *oReader) ([]byte, int) {
|
||||
// This is kind of ugly. Really the package name should not
|
||||
// even be included here.
|
||||
if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION {
|
||||
return
|
||||
if len(p) < 1 || p[0] != dwarf.DW_ABRV_FUNCTION {
|
||||
return p, -1
|
||||
}
|
||||
e := bytes.IndexByte(s.P, 0)
|
||||
e := bytes.IndexByte(p, 0)
|
||||
if e == -1 {
|
||||
return p, -1
|
||||
}
|
||||
if !bytes.Contains(p[:e], emptyPkg) {
|
||||
return p, -1
|
||||
}
|
||||
pkgprefix := []byte(r.pkgprefix)
|
||||
patched := bytes.Replace(p[:e], emptyPkg, pkgprefix, -1)
|
||||
return append(patched, p[e:]...), e
|
||||
}
|
||||
|
||||
func patchDWARFName(s *sym.Symbol, r *oReader) {
|
||||
patched, e := patchDWARFName1(s.P, r)
|
||||
if e == -1 {
|
||||
return
|
||||
}
|
||||
p := bytes.Index(s.P[:e], emptyPkg)
|
||||
if p == -1 {
|
||||
return
|
||||
}
|
||||
pkgprefix := []byte(r.pkgprefix)
|
||||
patched := bytes.Replace(s.P[:e], emptyPkg, pkgprefix, -1)
|
||||
|
||||
s.P = append(patched, s.P[e:]...)
|
||||
s.P = patched
|
||||
s.Attr.Set(sym.AttrReadOnly, false)
|
||||
delta := int64(len(s.P)) - s.Size
|
||||
s.Size = int64(len(s.P))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue