Skip to content

Commit d41b906

Browse files
committed
[dev.link] cmd/link: add PPC64 debugging option to encourage text section splits
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Jeremy Faller <[email protected]>
1 parent 18ee349 commit d41b906

File tree

2 files changed

+61
-45
lines changed

2 files changed

+61
-45
lines changed

src/cmd/link/internal/ld/data.go

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,37 +2247,52 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64
22472247

22482248
// Only break at outermost syms.
22492249

2250-
if ctxt.Arch.InFamily(sys.PPC64) && ldr.OuterSym(s) == 0 && ctxt.IsExternal() && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(ldr, s, isTramp) > 0x1c00000 {
2251-
// Set the length for the previous text section
2252-
sect.Length = va - sect.Vaddr
2253-
2254-
// Create new section, set the starting Vaddr
2255-
sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
2256-
sect.Vaddr = va
2257-
ldr.SetSymSect(s, sect)
2258-
2259-
// Create a symbol for the start of the secondary text sections
2260-
ntext := ldr.CreateSymForUpdate(fmt.Sprintf("runtime.text.%d", n), 0)
2261-
ntext.SetSect(sect)
2262-
if ctxt.IsAIX() {
2263-
// runtime.text.X must be a real symbol on AIX.
2264-
// Assign its address directly in order to be the
2265-
// first symbol of this new section.
2266-
ntext.SetType(sym.STEXT)
2267-
ntext.SetSize(int64(MINFUNC))
2268-
ntext.SetOnList(true)
2269-
ctxt.tramps = append(ctxt.tramps, ntext.Sym())
2270-
2271-
ntext.SetValue(int64(va))
2272-
va += uint64(ntext.Size())
2273-
2274-
if align := ldr.SymAlign(s); align != 0 {
2275-
va = uint64(Rnd(int64(va), int64(align)))
2276-
} else {
2277-
va = uint64(Rnd(int64(va), int64(Funcalign)))
2250+
// For debugging purposes, allow text size limit to be cranked down,
2251+
// so as to stress test the code that handles multiple text sections.
2252+
var textSizelimit uint64 = 0x1c00000
2253+
if *FlagDebugTextSize != 0 {
2254+
textSizelimit = uint64(*FlagDebugTextSize)
2255+
}
2256+
2257+
if ctxt.Arch.InFamily(sys.PPC64) && ldr.OuterSym(s) == 0 && ctxt.IsExternal() {
2258+
// Sanity check: make sure the limit is larger than any
2259+
// individual text symbol.
2260+
if funcsize > textSizelimit {
2261+
panic(fmt.Sprintf("error: ppc64 text size limit %d less than text symbol %s size of %d", textSizelimit, ldr.SymName(s), funcsize))
2262+
}
2263+
2264+
if va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(ldr, s, isTramp) > textSizelimit {
2265+
// Set the length for the previous text section
2266+
sect.Length = va - sect.Vaddr
2267+
2268+
// Create new section, set the starting Vaddr
2269+
sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
2270+
sect.Vaddr = va
2271+
ldr.SetSymSect(s, sect)
2272+
2273+
// Create a symbol for the start of the secondary text sections
2274+
ntext := ldr.CreateSymForUpdate(fmt.Sprintf("runtime.text.%d", n), 0)
2275+
ntext.SetSect(sect)
2276+
if ctxt.IsAIX() {
2277+
// runtime.text.X must be a real symbol on AIX.
2278+
// Assign its address directly in order to be the
2279+
// first symbol of this new section.
2280+
ntext.SetType(sym.STEXT)
2281+
ntext.SetSize(int64(MINFUNC))
2282+
ntext.SetOnList(true)
2283+
ctxt.tramps = append(ctxt.tramps, ntext.Sym())
2284+
2285+
ntext.SetValue(int64(va))
2286+
va += uint64(ntext.Size())
2287+
2288+
if align := ldr.SymAlign(s); align != 0 {
2289+
va = uint64(Rnd(int64(va), int64(align)))
2290+
} else {
2291+
va = uint64(Rnd(int64(va), int64(Funcalign)))
2292+
}
22782293
}
2294+
n++
22792295
}
2280-
n++
22812296
}
22822297

22832298
ldr.SetSymValue(s, 0)

src/cmd/link/internal/ld/main.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,23 @@ var (
7474
flagExtldflags = flag.String("extldflags", "", "pass `flags` to external linker")
7575
flagExtar = flag.String("extar", "", "archive program for buildmode=c-archive")
7676

77-
flagA = flag.Bool("a", false, "no-op (deprecated)")
78-
FlagC = flag.Bool("c", false, "dump call graph")
79-
FlagD = flag.Bool("d", false, "disable dynamic executable")
80-
flagF = flag.Bool("f", false, "ignore version mismatch")
81-
flagG = flag.Bool("g", false, "disable go package data checks")
82-
flagH = flag.Bool("h", false, "halt on error")
83-
flagN = flag.Bool("n", false, "dump symbol table")
84-
FlagS = flag.Bool("s", false, "disable symbol table")
85-
FlagW = flag.Bool("w", false, "disable DWARF generation")
86-
flag8 bool // use 64-bit addresses in symbol table
87-
flagInterpreter = flag.String("I", "", "use `linker` as ELF dynamic linker")
88-
FlagDebugTramp = flag.Int("debugtramp", 0, "debug trampolines")
89-
FlagStrictDups = flag.Int("strictdups", 0, "sanity check duplicate symbol contents during object file reading (1=warn 2=err).")
90-
FlagRound = flag.Int("R", -1, "set address rounding `quantum`")
91-
FlagTextAddr = flag.Int64("T", -1, "set text segment `address`")
92-
flagEntrySymbol = flag.String("E", "", "set `entry` symbol name")
77+
flagA = flag.Bool("a", false, "no-op (deprecated)")
78+
FlagC = flag.Bool("c", false, "dump call graph")
79+
FlagD = flag.Bool("d", false, "disable dynamic executable")
80+
flagF = flag.Bool("f", false, "ignore version mismatch")
81+
flagG = flag.Bool("g", false, "disable go package data checks")
82+
flagH = flag.Bool("h", false, "halt on error")
83+
flagN = flag.Bool("n", false, "dump symbol table")
84+
FlagS = flag.Bool("s", false, "disable symbol table")
85+
FlagW = flag.Bool("w", false, "disable DWARF generation")
86+
flag8 bool // use 64-bit addresses in symbol table
87+
flagInterpreter = flag.String("I", "", "use `linker` as ELF dynamic linker")
88+
FlagDebugTramp = flag.Int("debugtramp", 0, "debug trampolines")
89+
FlagDebugTextSize = flag.Int("debugppc64textsize", 0, "debug PPC64 text section max")
90+
FlagStrictDups = flag.Int("strictdups", 0, "sanity check duplicate symbol contents during object file reading (1=warn 2=err).")
91+
FlagRound = flag.Int("R", -1, "set address rounding `quantum`")
92+
FlagTextAddr = flag.Int64("T", -1, "set text segment `address`")
93+
flagEntrySymbol = flag.String("E", "", "set `entry` symbol name")
9394

9495
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
9596
memprofile = flag.String("memprofile", "", "write memory profile to `file`")

0 commit comments

Comments
 (0)