return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
}
- if /* x86 */ c1 == 0x4c && c2 == 0x01 || /* x86_64 */ c1 == 0x64 && c2 == 0x86 || /* armv7 */ c1 == 0xc4 && c2 == 0x01 {
+ switch c1<<8 | c2 {
+ case 0x4c01, // 386
+ 0x6486, // amd64
+ 0xc401, // arm
+ 0x64aa: // arm64
ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
if err != nil {
IMAGE_REL_THUMB_BRANCH24 = 0x0014
IMAGE_REL_THUMB_BLX23 = 0x0015
IMAGE_REL_ARM_PAIR = 0x0016
+ IMAGE_REL_ARM64_ABSOLUTE = 0x0000
+ IMAGE_REL_ARM64_ADDR32 = 0x0001
+ IMAGE_REL_ARM64_ADDR32NB = 0x0002
+ IMAGE_REL_ARM64_BRANCH26 = 0x0003
+ IMAGE_REL_ARM64_PAGEBASE_REL21 = 0x0004
+ IMAGE_REL_ARM64_REL21 = 0x0005
+ IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006
+ IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007
+ IMAGE_REL_ARM64_SECREL = 0x0008
+ IMAGE_REL_ARM64_SECREL_LOW12A = 0x0009
+ IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A
+ IMAGE_REL_ARM64_SECREL_LOW12L = 0x000B
+ IMAGE_REL_ARM64_TOKEN = 0x000C
+ IMAGE_REL_ARM64_SECTION = 0x000D
+ IMAGE_REL_ARM64_ADDR64 = 0x000E
+ IMAGE_REL_ARM64_BRANCH19 = 0x000F
+ IMAGE_REL_ARM64_BRANCH14 = 0x0010
+ IMAGE_REL_ARM64_REL32 = 0x0011
)
// TODO(crawshaw): de-duplicate these symbols with cmd/internal/ld, ideally in debug/pe.
case IMAGE_REL_ARM_BRANCH24:
rType = objabi.R_CALLARM
+ rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
+ }
+
+ case sys.ARM64:
+ switch r.Type {
+ default:
+ return nil, nil, fmt.Errorf("%s: %v: unknown ARM64 relocation type %v", pn, sectsyms[rsect], r.Type)
+
+ case IMAGE_REL_ARM64_ADDR32, IMAGE_REL_ARM64_ADDR32NB:
+ rType = objabi.R_ADDR
+
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
}
}
}
}
-func TestPErsrc(t *testing.T) {
+func TestPErsrcBinutils(t *testing.T) {
// Test that PE rsrc section is handled correctly (issue 39658).
testenv.MustHaveGoBuild(t)
- if runtime.GOARCH != "amd64" || runtime.GOOS != "windows" {
- t.Skipf("this is a windows/amd64-only test")
+ if (runtime.GOARCH != "386" && runtime.GOARCH != "amd64") || runtime.GOOS != "windows" {
+ // This test is limited to amd64 and 386, because binutils is limited as such
+ t.Skipf("this is only for windows/amd64 and windows/386")
}
t.Parallel()
- tmpdir, err := ioutil.TempDir("", "TestPErsrc")
+ tmpdir, err := ioutil.TempDir("", "TestPErsrcBinutils")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
- pkgdir := filepath.Join("testdata", "testPErsrc")
+ pkgdir := filepath.Join("testdata", "pe-binutils")
exe := filepath.Join(tmpdir, "a.exe")
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
cmd.Dir = pkgdir
if !bytes.Contains(b, []byte("Hello Gophers!")) {
t.Fatalf("binary does not contain expected content")
}
+}
+
+func TestPErsrcLLVM(t *testing.T) {
+ // Test that PE rsrc section is handled correctly (issue 39658).
+ testenv.MustHaveGoBuild(t)
+
+ if runtime.GOOS != "windows" {
+ t.Skipf("this is a windows-only test")
+ }
+
+ t.Parallel()
+
+ tmpdir, err := ioutil.TempDir("", "TestPErsrcLLVM")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tmpdir)
- pkgdir = filepath.Join("testdata", "testPErsrc-complex")
- exe = filepath.Join(tmpdir, "a.exe")
- cmd = exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
+ pkgdir := filepath.Join("testdata", "pe-llvm")
+ exe := filepath.Join(tmpdir, "a.exe")
+ cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
cmd.Dir = pkgdir
// cmd.Env = append(os.Environ(), "GOOS=windows", "GOARCH=amd64") // uncomment if debugging in a cross-compiling environment
- out, err = cmd.CombinedOutput()
+ out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("building failed: %v, output:\n%s", err, out)
}
// Check that the binary contains the rsrc data
- b, err = ioutil.ReadFile(exe)
+ b, err := ioutil.ReadFile(exe)
if err != nil {
t.Fatalf("reading output failed: %v", err)
}
// Test that a PE rsrc section is handled correctly (issue 39658).
//
-// rsrc.syso is created with:
-// windres -i a.rc -o rsrc.syso -O coff
-// on windows-amd64-2016 builder, where a.rc is a text file with
-// the following content:
+// rsrc.syso is created using binutils with:
+// {x86_64,i686}-w64-mingw32-windres -i a.rc -o rsrc_$GOARCH.syso -O coff
+// where a.rc is a text file with the following content:
//
// resname RCDATA {
// "Hello Gophers!\0",
// have been created by llvm-rc or msvc's rc.exe, which means there's the
// @feat.00 symbol as well as split .rsrc$00 and .rsrc$01 section to deal with.
//
-// rsrc.syso is created with:
-// windres -i a.rc -o rsrc.syso -O coff
+// rsrc.syso is created using llvm with:
+// {i686,x86_64,armv7,arm64}-w64-mingw32-windres -i a.rc -o rsrc_$GOARCH.syso -O coff
// where this windres calls into llvm-rc and llvm-cvtres. The source file,
// a.rc, simply contains a reference to its own bytes:
//