From: Cherry Zhang Date: Tue, 23 Jun 2020 21:29:17 +0000 (-0400) Subject: [dev.link] cmd/link: fix data race on AIX X-Git-Tag: go1.16beta1~1378^2~77 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a89fd32316954dea9fa87e45b266eb2e648f7f8e;p=gostls13.git [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 TryBot-Result: Gobot Gobot Reviewed-by: Than McIntosh Reviewed-by: Jeremy Faller --- diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go index e5ed847b54..9e3b8e2a0c 100644 --- a/src/cmd/link/internal/ld/xcoff.go +++ b/src/cmd/link/internal/ld/xcoff.go @@ -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)),