mirror of
https://github.com/golang/go
synced 2024-11-18 16:04:44 -07: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:
parent
da13da1fce
commit
d66fc90a0d
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user