1
0
mirror of https://github.com/golang/go synced 2024-09-30 19:38:33 -06:00

cmd/link: round up default start address to alignment

If the -R flag (the segment alignment) is specified but the -T
flag (start address) is not, currently the default start address
may be under-aligned, and some math in the linker may be broken.
Round up the start address to align it.

Fixes #62064.

Change-Id: I3b98c9d0cf7d3cd944b9436a36808899d2e52572
Reviewed-on: https://go-review.googlesource.com/c/go/+/527822
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Cherry Mui 2023-09-13 12:50:17 -04:00
parent da13da1fce
commit d66fc90a0d
14 changed files with 85 additions and 76 deletions

View File

@ -498,3 +498,28 @@ func TestIssue51939(t *testing.T) {
}
}
}
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)
}
}

View File

@ -86,13 +86,12 @@ func archinit(ctxt *ld.Link) {
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
@ -100,7 +99,7 @@ func archinit(ctxt *ld.Link) {
*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 */
@ -112,12 +111,12 @@ func archinit(ctxt *ld.Link) {
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

View File

@ -84,13 +84,12 @@ func archinit(ctxt *ld.Link) {
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,
@ -100,12 +99,12 @@ func archinit(ctxt *ld.Link) {
// 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

View File

@ -86,13 +86,12 @@ func archinit(ctxt *ld.Link) {
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,
@ -100,21 +99,21 @@ func archinit(ctxt *ld.Link) {
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

View File

@ -98,7 +98,7 @@ var (
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")

View File

@ -1149,11 +1149,11 @@ func Peinit(ctxt *Link) {
}
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)
}
}

View File

@ -544,15 +544,14 @@ func Xcoffinit(ctxt *Link) {
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

View File

@ -53,11 +53,11 @@ func archinit(ctxt *ld.Link) {
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)
}
}
}

View File

@ -91,12 +91,12 @@ func archinit(ctxt *ld.Link) {
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)
}
}
}

View File

@ -88,24 +88,23 @@ func archinit(ctxt *ld.Link) {
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

View File

@ -92,24 +92,23 @@ func archinit(ctxt *ld.Link) {
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)

View File

@ -60,12 +60,12 @@ func archinit(ctxt *ld.Link) {
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)
}

View File

@ -81,11 +81,11 @@ func archinit(ctxt *ld.Link) {
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)
}
}
}

View File

@ -82,21 +82,11 @@ func archinit(ctxt *ld.Link) {
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 */
@ -106,12 +96,12 @@ func archinit(ctxt *ld.Link) {
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