cmd/link: avoid crash on undefined func sym with external linking

Fix a buglet in relocation processing that crops up with external
linking when you have an undefined function symbol that also has a
prototype (as if it were being defined in assembly src).

Fixes #47993.

Change-Id: Ib655492a63b205ffdc124cfd0cb7f7b731571821
Reviewed-on: https://go-review.googlesource.com/c/go/+/345473
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
Than McIntosh 2021-08-26 15:59:36 -04:00
parent 37d4532867
commit 014a9720f9
2 changed files with 53 additions and 0 deletions

View file

@ -0,0 +1,48 @@
# Test case for issue 47993, in which the linker crashes
# on a bad input instead of issuing an error and exiting.
# This test requires external linking, so use cgo as a proxy
[!cgo] skip
! go build -ldflags='-linkmode=external' .
! stderr 'panic'
stderr '^.*unreachable sym in relocation.*'
-- go.mod --
module issue47993
go 1.16
-- main.go --
package main
type M struct {
b bool
}
// Note the body-less func def here. This is what causes the problems.
func (m *M) run(fp func())
func doit(m *M) {
InAsm()
m.run(func() {
})
}
func main() {
m := &M{true}
doit(m)
}
func InAsm()
-- main.s --
// Add an assembly function so as to leave open the possibility
// that body-less functions in Go might be defined in assembly.
// Currently we just need an empty file here.

View file

@ -436,6 +436,11 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
if weak && !ldr.AttrReachable(rs) {
continue
}
if ldr.SymSect(rs) == nil {
st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs))
continue
}
// The method offset tables using this relocation expect the offset to be relative
// to the start of the first text section, even if there are multiple.
if ldr.SymSect(rs).Name == ".text" {