[dev.link] cmd/link: fix data race on AIX

On AIX, in relocsym we call Xcoffadddynrel, which adds a
relocation record to a global array. relocsym already runs in
parallel. In the past we only parallelize over segments, and
we call Xcoffadddynrel only for symbols in data segment, so it is
effectively called sequentially. In CL 239197 we started to do
more fine-grained parallelism, so we need to make sure it is safe
to call Xcoffadddynrel in parallel.

Fix AIX build.

Change-Id: I3128193995a5a99d9fa04c8e728e590f17298da3
Reviewed-on: https://go-review.googlesource.com/c/go/+/239561
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
Cherry Zhang 2020-06-23 17:29:17 -04:00
parent f0cf4d4d7f
commit a89fd32316
1 changed files with 19 additions and 0 deletions

View File

@ -16,6 +16,7 @@ import (
"path/filepath"
"sort"
"strings"
"sync"
)
// This file handles all algorithms related to XCOFF files generation.
@ -417,6 +418,7 @@ type xcoffFile struct {
dynLibraries map[string]int // Dynamic libraries in .loader section. The integer represents its import file number (- 1)
loaderSymbols []*xcoffLoaderSymbol // symbols inside .loader symbol table
loaderReloc []*xcoffLoaderReloc // Reloc that must be made inside loader
sync.Mutex // currently protect loaderReloc
}
// Var used by XCOFF Generation algorithms
@ -1265,7 +1267,9 @@ func Xcoffadddynrel(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader
xldr.rtype = 0x3F<<8 + XCOFF_R_POS
}
xfile.Lock()
xfile.loaderReloc = append(xfile.loaderReloc, xldr)
xfile.Unlock()
return true
}
@ -1398,6 +1402,21 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
off := hdr.Lrldoff // current offset is the same of reloc offset
/* Reloc */
// Ensure deterministic order
sort.Slice(f.loaderReloc, func(i, j int) bool {
r1, r2 := f.loaderReloc[i], f.loaderReloc[j]
if r1.sym != r2.sym {
return r1.sym < r2.sym
}
if r1.roff != r2.roff {
return r1.roff < r2.roff
}
if r1.rtype != r2.rtype {
return r1.rtype < r2.rtype
}
return r1.symndx < r2.symndx
})
ep := ldr.Lookup(*flagEntrySymbol, 0)
xldr := &XcoffLdRel64{
Lvaddr: uint64(ldr.SymValue(ep)),