ObjFlagShared = 1 << iota // this object is built with -shared
ObjFlagNeedNameExpansion // the linker needs to expand `"".` to package path in symbol names
ObjFlagFromAssembly // object is from asm src, not go
+ ObjFlagUnlinkable // unlinkable package (linker will emit an error)
)
// Sym.Flag
func (r *Reader) Shared() bool { return r.Flags()&ObjFlagShared != 0 }
func (r *Reader) NeedNameExpansion() bool { return r.Flags()&ObjFlagNeedNameExpansion != 0 }
func (r *Reader) FromAssembly() bool { return r.Flags()&ObjFlagFromAssembly != 0 }
+func (r *Reader) Unlinkable() bool { return r.Flags()&ObjFlagUnlinkable != 0 }
"strings"
)
+const UnlinkablePkg = "<unlinkable>" // invalid package path, used when compiled without -p flag
+
// Entry point of writing new object file.
func WriteObjFile(ctxt *Link, b *bio.Writer) {
if ctxt.Flag_shared {
flags |= goobj.ObjFlagShared
}
+ if w.pkgpath == UnlinkablePkg {
+ flags |= goobj.ObjFlagUnlinkable
+ }
if w.pkgpath == "" {
flags |= goobj.ObjFlagNeedNameExpansion
}
objidx: uint32(len(l.objs)),
}
+ if r.Unlinkable() {
+ log.Fatalf("link: unlinkable object (from package %s) - compiler requires -p flag", lib.Pkg)
+ }
+
// Autolib
lib.Autolib = append(lib.Autolib, r.Autolib()...)
}
}
}
+
+func TestUnlinkableObj(t *testing.T) {
+ // Test that the linker emits an error with unlinkable object.
+ testenv.MustHaveGoBuild(t)
+ t.Parallel()
+
+ tmpdir := t.TempDir()
+
+ src := filepath.Join(tmpdir, "x.go")
+ obj := filepath.Join(tmpdir, "x.o")
+ err := ioutil.WriteFile(src, []byte("package main\nfunc main() {}\n"), 0666)
+ if err != nil {
+ t.Fatalf("failed to write source file: %v", err)
+ }
+ cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", obj, src) // without -p
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("compile failed: %v. output:\n%s", err, out)
+ }
+ cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", obj)
+ out, err = cmd.CombinedOutput()
+ if err == nil {
+ t.Fatalf("link did not fail")
+ }
+ if !bytes.Contains(out, []byte("unlinkable object")) {
+ t.Errorf("did not see expected error message. out:\n%s", out)
+ }
+}