]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: round up default start address to alignment
authorCherry Mui <cherryyz@google.com>
Wed, 13 Sep 2023 16:50:17 +0000 (12:50 -0400)
committerCherry Mui <cherryyz@google.com>
Wed, 13 Sep 2023 19:32:19 +0000 (19:32 +0000)
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>

14 files changed:
src/cmd/link/elf_test.go
src/cmd/link/internal/amd64/obj.go
src/cmd/link/internal/arm/obj.go
src/cmd/link/internal/arm64/obj.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/ld/pe.go
src/cmd/link/internal/ld/xcoff.go
src/cmd/link/internal/loong64/obj.go
src/cmd/link/internal/mips/obj.go
src/cmd/link/internal/mips64/obj.go
src/cmd/link/internal/ppc64/obj.go
src/cmd/link/internal/riscv64/obj.go
src/cmd/link/internal/s390x/obj.go
src/cmd/link/internal/x86/obj.go

index d6621458473f0dde30b85f4a6968ed74d4a9f24d..902ce28b104e4b85d224665f614ae5e394b8a59e 100644 (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)
+       }
+}
index b99cdbc356252ab78aac3bfddb23878cdc3c03a1..3a6141b9091eb6068821c9bfbcea3265491bd0a1 100644 (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
index 52fd5b652363982735c933c73b979c0009ffeb2a..3a1830ce10e11756ca62240952abc03f0396e18b 100644 (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
index 34b693ed6c8cf7dd5108a7b1d3cf824d70acff4d..3d358155badbca1e07d63b55dd4f7c790c48ace1 100644 (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
index aa6c00ce88d9c1eb3359ff7762782825b316c4d2..b978cfc7d491900412baaa8e54522ae9ccabb37a 100644 (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")
index 1502b3eb396592c6c2e01e22e5477c1737dc0c01..a2c5a99e8e8773b9bd14efe4c37c603557d14c0f 100644 (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)
        }
 }
 
index 158a86f61d8715a2527a466b4905758ddb26b8c3..1e4a85a12e1bd0c47115618e2a19c8600f95037d 100644 (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
index fd193a24453a8331ff41a35c9785f0bad319e70d..b68ed494f6960ebe671c33211b8d13a194f73afb 100644 (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)
+               }
        }
 }
index 1caddac6be03a4584667859f958b1de45ebd5632..e07ee0b208673da6db8a6d77a3755f5dfe517794 100644 (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)
+               }
        }
 }
 
index 7fb19e92ac74666dc441accb8e69886daefabb9e..193ad1f27110b8d01034016b6d4ba06e64859f5f 100644 (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
index 7de0f8eac656e6c2544838a931709057de9c7da9..703c8ec2e85c0cd29e9f874893eafaa0c108f11a 100644 (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)
index 1532d29366c164a4f5753c3f528d871ab5a8152d..a18e8369fdcf07ec84c4d1c282e9dc813c615b63 100644 (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)
        }
index c2386fb9e9232b7d2ab4b997fd5dde8f2f50e536..76aa962a82b954a5e5a7cb751524ba96eeae82da 100644 (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)
+               }
        }
 }
index 6ccb8e093f322bc1626210c9b9b13c68336e0750..4336f01ea3d53677dff711a7627c090dc556f712 100644 (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