]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: fix data race on AIX
authorCherry Zhang <cherryyz@google.com>
Tue, 23 Jun 2020 21:29:17 +0000 (17:29 -0400)
committerCherry Zhang <cherryyz@google.com>
Wed, 24 Jun 2020 15:04:05 +0000 (15:04 +0000)
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>
src/cmd/link/internal/ld/xcoff.go

index e5ed847b54c0a27ac2d3ddb64c63be8fdea82ab5..9e3b8e2a0c6befa603e2de8a49e2e6c8583bf106 100644 (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)),