]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: add PPC64 debugging option to encourage text section splits
authorThan McIntosh <thanm@google.com>
Tue, 7 Jul 2020 16:54:46 +0000 (12:54 -0400)
committerThan McIntosh <thanm@google.com>
Mon, 10 Aug 2020 11:38:46 +0000 (11:38 +0000)
Add a new debugging command line option (-debugppc64textsize=N) that
forces the start of a new text section after ".text" hits N bytes as
opposed to the architected limit of 2^26. This is intended to enable
testing of the linker code paths that handle multiple .text sections
on PPC64 without resorting to building giant applications.

Updates #20492.

Change-Id: I74ab7fd1e412e9124de5bd0d8d248c5e73225ae3
Reviewed-on: https://go-review.googlesource.com/c/go/+/241073
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/main.go

index b9e2408942bdabbfe48816ff388fde15d8fb0eab..dc7096ea8cc80940d08a930f87160d8efda3f84f 100644 (file)
@@ -2247,37 +2247,52 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64
 
        // Only break at outermost syms.
 
-       if ctxt.Arch.InFamily(sys.PPC64) && ldr.OuterSym(s) == 0 && ctxt.IsExternal() && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(ldr, s, isTramp) > 0x1c00000 {
-               // Set the length for the previous text section
-               sect.Length = va - sect.Vaddr
-
-               // Create new section, set the starting Vaddr
-               sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
-               sect.Vaddr = va
-               ldr.SetSymSect(s, sect)
-
-               // Create a symbol for the start of the secondary text sections
-               ntext := ldr.CreateSymForUpdate(fmt.Sprintf("runtime.text.%d", n), 0)
-               ntext.SetSect(sect)
-               if ctxt.IsAIX() {
-                       // runtime.text.X must be a real symbol on AIX.
-                       // Assign its address directly in order to be the
-                       // first symbol of this new section.
-                       ntext.SetType(sym.STEXT)
-                       ntext.SetSize(int64(MINFUNC))
-                       ntext.SetOnList(true)
-                       ctxt.tramps = append(ctxt.tramps, ntext.Sym())
-
-                       ntext.SetValue(int64(va))
-                       va += uint64(ntext.Size())
-
-                       if align := ldr.SymAlign(s); align != 0 {
-                               va = uint64(Rnd(int64(va), int64(align)))
-                       } else {
-                               va = uint64(Rnd(int64(va), int64(Funcalign)))
+       // For debugging purposes, allow text size limit to be cranked down,
+       // so as to stress test the code that handles multiple text sections.
+       var textSizelimit uint64 = 0x1c00000
+       if *FlagDebugTextSize != 0 {
+               textSizelimit = uint64(*FlagDebugTextSize)
+       }
+
+       if ctxt.Arch.InFamily(sys.PPC64) && ldr.OuterSym(s) == 0 && ctxt.IsExternal() {
+               // Sanity check: make sure the limit is larger than any
+               // individual text symbol.
+               if funcsize > textSizelimit {
+                       panic(fmt.Sprintf("error: ppc64 text size limit %d less than text symbol %s size of %d", textSizelimit, ldr.SymName(s), funcsize))
+               }
+
+               if va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(ldr, s, isTramp) > textSizelimit {
+                       // Set the length for the previous text section
+                       sect.Length = va - sect.Vaddr
+
+                       // Create new section, set the starting Vaddr
+                       sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
+                       sect.Vaddr = va
+                       ldr.SetSymSect(s, sect)
+
+                       // Create a symbol for the start of the secondary text sections
+                       ntext := ldr.CreateSymForUpdate(fmt.Sprintf("runtime.text.%d", n), 0)
+                       ntext.SetSect(sect)
+                       if ctxt.IsAIX() {
+                               // runtime.text.X must be a real symbol on AIX.
+                               // Assign its address directly in order to be the
+                               // first symbol of this new section.
+                               ntext.SetType(sym.STEXT)
+                               ntext.SetSize(int64(MINFUNC))
+                               ntext.SetOnList(true)
+                               ctxt.tramps = append(ctxt.tramps, ntext.Sym())
+
+                               ntext.SetValue(int64(va))
+                               va += uint64(ntext.Size())
+
+                               if align := ldr.SymAlign(s); align != 0 {
+                                       va = uint64(Rnd(int64(va), int64(align)))
+                               } else {
+                                       va = uint64(Rnd(int64(va), int64(Funcalign)))
+                               }
                        }
+                       n++
                }
-               n++
        }
 
        ldr.SetSymValue(s, 0)
index 3702f28dd85604ec8672f2ff1d913517342fc017..4885c4f57ebf9057a09eca3489df60bf79f022b4 100644 (file)
@@ -74,22 +74,23 @@ var (
        flagExtldflags = flag.String("extldflags", "", "pass `flags` to external linker")
        flagExtar      = flag.String("extar", "", "archive program for buildmode=c-archive")
 
-       flagA           = flag.Bool("a", false, "no-op (deprecated)")
-       FlagC           = flag.Bool("c", false, "dump call graph")
-       FlagD           = flag.Bool("d", false, "disable dynamic executable")
-       flagF           = flag.Bool("f", false, "ignore version mismatch")
-       flagG           = flag.Bool("g", false, "disable go package data checks")
-       flagH           = flag.Bool("h", false, "halt on error")
-       flagN           = flag.Bool("n", false, "dump symbol table")
-       FlagS           = flag.Bool("s", false, "disable symbol table")
-       FlagW           = flag.Bool("w", false, "disable DWARF generation")
-       flag8           bool // use 64-bit addresses in symbol table
-       flagInterpreter = flag.String("I", "", "use `linker` as ELF dynamic linker")
-       FlagDebugTramp  = flag.Int("debugtramp", 0, "debug trampolines")
-       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`")
-       FlagTextAddr    = flag.Int64("T", -1, "set text segment `address`")
-       flagEntrySymbol = flag.String("E", "", "set `entry` symbol name")
+       flagA             = flag.Bool("a", false, "no-op (deprecated)")
+       FlagC             = flag.Bool("c", false, "dump call graph")
+       FlagD             = flag.Bool("d", false, "disable dynamic executable")
+       flagF             = flag.Bool("f", false, "ignore version mismatch")
+       flagG             = flag.Bool("g", false, "disable go package data checks")
+       flagH             = flag.Bool("h", false, "halt on error")
+       flagN             = flag.Bool("n", false, "dump symbol table")
+       FlagS             = flag.Bool("s", false, "disable symbol table")
+       FlagW             = flag.Bool("w", false, "disable DWARF generation")
+       flag8             bool // use 64-bit addresses in symbol table
+       flagInterpreter   = flag.String("I", "", "use `linker` as ELF dynamic linker")
+       FlagDebugTramp    = flag.Int("debugtramp", 0, "debug trampolines")
+       FlagDebugTextSize = flag.Int("debugppc64textsize", 0, "debug PPC64 text section max")
+       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`")
+       FlagTextAddr      = flag.Int64("T", -1, "set text segment `address`")
+       flagEntrySymbol   = flag.String("E", "", "set `entry` symbol name")
 
        cpuprofile     = flag.String("cpuprofile", "", "write cpu profile to `file`")
        memprofile     = flag.String("memprofile", "", "write memory profile to `file`")