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>
--- /dev/null
+
+# 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.
+
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" {