}
}
}
+
+func TestFlagR(t *testing.T) {
+ // Test that using the -R flag to specify a (large) alignment generates
+ // a working binary.
+ // (Test only on ELF for now. The alignment allowed differs from platform
+ // to platform.)
+ testenv.MustHaveGoBuild(t)
+ t.Parallel()
+ tmpdir := t.TempDir()
+ src := filepath.Join(tmpdir, "x.go")
+ if err := os.WriteFile(src, []byte(goSource), 0444); err != nil {
+ t.Fatal(err)
+ }
+ exe := filepath.Join(tmpdir, "x.exe")
+
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-R=0x100000", "-o", exe, src)
+ if out, err := cmd.CombinedOutput(); err != nil {
+ t.Fatalf("build failed: %v, output:\n%s", err, out)
+ }
+
+ cmd = testenv.Command(t, exe)
+ if out, err := cmd.CombinedOutput(); err != nil {
+ t.Errorf("executable failed to run: %v\n%s", err, out)
+ }
+}
case objabi.Hplan9: /* plan 9 */
ld.HEADR = 32 + 8
-
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x200000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x200000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x200000, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hdarwin: /* apple MACH */
ld.HEADR = ld.INITIAL_MACHO_HEADR
*ld.FlagRound = 4096
}
if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x1000000 + int64(ld.HEADR)
+ *ld.FlagTextAddr = ld.Rnd(0x1000000, *ld.FlagRound) + int64(ld.HEADR)
}
case objabi.Hlinux, /* elf64 executable */
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = (1 << 22) + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 4096
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(1<<22, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hwindows: /* PE executable */
// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
case objabi.Hplan9: /* plan 9 */
ld.HEADR = 32
-
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 4128
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 4096
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(4096, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hlinux, /* arm elf */
objabi.Hfreebsd,
// with dynamic linking
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x10000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hwindows: /* PE executable */
// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
case objabi.Hplan9: /* plan 9 */
ld.HEADR = 32
-
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 4096 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 4096
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(4096, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hlinux, /* arm64 elf */
objabi.Hfreebsd,
objabi.Hopenbsd:
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x10000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hdarwin: /* apple MACH */
ld.HEADR = ld.INITIAL_MACHO_HEADR
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 1<<32 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 16384 // 16K page alignment
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(1<<32, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hwindows: /* PE executable */
// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
FlagDebugTextSize = flag.Int("debugtextsize", 0, "debug text section max size")
flagDebugNosplit = flag.Bool("debugnosplit", false, "dump nosplit call graph")
FlagStrictDups = flag.Int("strictdups", 0, "sanity check duplicate symbol contents during object file reading (1=warn 2=err).")
- FlagRound = flag.Int("R", -1, "set address rounding `quantum`")
+ FlagRound = flag.Int64("R", -1, "set address rounding `quantum`")
FlagTextAddr = flag.Int64("T", -1, "set the start address of text symbols")
flagEntrySymbol = flag.String("E", "", "set `entry` symbol name")
flagPruneWeakMap = flag.Bool("pruneweakmap", true, "prune weak mapinit refs")
}
HEADR = PEFILEHEADR
- if *FlagTextAddr == -1 {
- *FlagTextAddr = PEBASE + int64(PESECTHEADR)
- }
if *FlagRound == -1 {
- *FlagRound = int(PESECTALIGN)
+ *FlagRound = PESECTALIGN
+ }
+ if *FlagTextAddr == -1 {
+ *FlagTextAddr = Rnd(PEBASE, *FlagRound) + int64(PESECTHEADR)
}
}
xfile.dynLibraries = make(map[string]int)
HEADR = int32(Rnd(XCOFFHDRRESERVE, XCOFFSECTALIGN))
- if *FlagTextAddr != -1 {
- Errorf(nil, "-T not available on AIX")
- }
- *FlagTextAddr = XCOFFTEXTBASE + int64(HEADR)
if *FlagRound != -1 {
Errorf(nil, "-R not available on AIX")
}
- *FlagRound = int(XCOFFSECTALIGN)
-
+ *FlagRound = XCOFFSECTALIGN
+ if *FlagTextAddr != -1 {
+ Errorf(nil, "-T not available on AIX")
+ }
+ *FlagTextAddr = Rnd(XCOFFTEXTBASE, *FlagRound) + int64(HEADR)
}
// SYMBOL TABLE
case objabi.Hlinux: /* loong64 elf */
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x10000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR)
+ }
}
}
case objabi.Hlinux: /* mips elf */
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x10000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR)
+ }
}
}
case objabi.Hplan9: /* plan 9 */
ld.HEADR = 32
-
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 16*1024 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 16 * 1024
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(16*1024, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hlinux, /* mips64 elf */
objabi.Hopenbsd:
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x10000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR)
+ }
}
dynSymCount = 0
case objabi.Hplan9: /* plan 9 */
ld.HEADR = 32
-
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 4128
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 4096
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(4096, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hlinux, /* ppc64 elf */
objabi.Hopenbsd:
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x10000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Haix:
ld.Xcoffinit(ctxt)
case objabi.Hlinux, objabi.Hfreebsd:
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x10000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR)
+ }
default:
ld.Exitf("unknown -H option: %v", ctxt.HeadType)
}
case objabi.Hlinux: // s390x ELF
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 0x10000
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR)
+ }
}
}
case objabi.Hplan9: /* plan 9 */
ld.HEADR = 32
-
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 4096 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 4096
}
-
- case objabi.Hdarwin: /* apple MACH */
- ld.HEADR = ld.INITIAL_MACHO_HEADR
if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 4096 + int64(ld.HEADR)
- }
- if *ld.FlagRound == -1 {
- *ld.FlagRound = 4096
+ *ld.FlagTextAddr = ld.Rnd(4096, *ld.FlagRound) + int64(ld.HEADR)
}
case objabi.Hlinux, /* elf32 executable */
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
- if *ld.FlagTextAddr == -1 {
- *ld.FlagTextAddr = 0x08048000 + int64(ld.HEADR)
- }
if *ld.FlagRound == -1 {
*ld.FlagRound = 4096
}
+ if *ld.FlagTextAddr == -1 {
+ *ld.FlagTextAddr = ld.Rnd(0x08048000, *ld.FlagRound) + int64(ld.HEADR)
+ }
case objabi.Hwindows: /* PE executable */
// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit