]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: apply DWARF relocations while doing compression
authorCherry Zhang <cherryyz@google.com>
Wed, 10 Apr 2019 14:18:52 +0000 (10:18 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 19 Apr 2019 18:25:20 +0000 (18:25 +0000)
We are preparing for applying relocations to the output buffer.
However, for DWARF compression, relocations need to be applied
before compression, but we don't have an output buffer at that
time. We also cannot delay DWARF compression to when we mmap the
output file, because we need the size of the DWARF sections to
compute the file size.

Instead of applying all the relocations together, we apply
relocations in DWARF sections one symbol at a time, right before
it is writing out for compression. As the symbol content may be
in read-only memory (in the future), we use a temporary buffer
for applying the relocations, and immediately write it out.

If compression is not used, relocations are still applied all
together.

This is in preparation for mmap'ing input files read-only.

Change-Id: Iae6d2dd71313897d5054bcc458d3bb78075b30c3
Reviewed-on: https://go-review.googlesource.com/c/go/+/171397
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/main.go

index 04fe3cb3b5283fafc455a4d800729377f5e74668..7f4fe71cb42cf73c521e44b8c10a45eaa7d32ae5 100644 (file)
@@ -2385,6 +2385,12 @@ func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte {
                log.Fatalf("NewWriterLevel failed: %s", err)
        }
        for _, sym := range syms {
+               // sym.P may be read-only. Apply relocations in a
+               // temporary buffer, and immediately write it out.
+               oldP := sym.P
+               ctxt.relocbuf = append(ctxt.relocbuf[:0], sym.P...)
+               sym.P = ctxt.relocbuf
+               relocsym(ctxt, sym)
                if _, err := z.Write(sym.P); err != nil {
                        log.Fatalf("compression failed: %s", err)
                }
@@ -2399,6 +2405,14 @@ func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte {
                        }
                        i -= int64(n)
                }
+               // Restore sym.P, for 1. not holding temp buffer live
+               // unnecessarily, 2. if compression is not beneficial,
+               // we'll go back to use the uncompressed contents, in
+               // which case we still need sym.P.
+               sym.P = oldP
+               for i := range sym.R {
+                       sym.R[i].Done = false
+               }
        }
        if err := z.Close(); err != nil {
                log.Fatalf("compression failed: %s", err)
index 9e7fea0101125d3007d46661b8d96e96a77aee49..974c7ed329383fc170d428089d36904f9b35dc0a 100644 (file)
@@ -2125,9 +2125,9 @@ func dwarfaddelfsectionsyms(ctxt *Link) {
        }
 }
 
-// dwarfcompress compresses the DWARF sections. This must happen after
-// relocations are applied. After this, dwarfp will contain a
-// different (new) set of symbols, and sections may have been replaced.
+// dwarfcompress compresses the DWARF sections. Relocations are applied
+// on the fly. After this, dwarfp will contain a different (new) set of
+// symbols, and sections may have been replaced.
 func dwarfcompress(ctxt *Link) {
        supported := ctxt.IsELF || ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Hdarwin
        if !ctxt.compressDWARF || !supported || ctxt.LinkMode != LinkInternal {
@@ -2161,6 +2161,7 @@ func dwarfcompress(ctxt *Link) {
                }
        }
        dwarfp = newDwarfp
+       ctxt.relocbuf = nil // no longer needed, don't hold it live
 
        // Re-compute the locations of the compressed DWARF symbols
        // and sections, since the layout of these within the file is
index a7609b9c7cd9bf7eff514c8ff35f89a2682cae1c..d3ffacf54e370fa9149e07b9589e4c8ea86614be 100644 (file)
@@ -93,6 +93,8 @@ type Link struct {
 
        compUnits         []*compilationUnit // DWARF compilation units
        compUnitByPackage map[*sym.Library]*compilationUnit
+
+       relocbuf []byte // temporary buffer for applying relocations
 }
 
 type unresolvedSymKey struct {
index 1b2d376fd4a9d3a166fae5f540dd0420b48fbe84..aac37883e1bb718173c04165fb451165e2e90d0f 100644 (file)
@@ -239,8 +239,8 @@ func Main(arch *sys.Arch, theArch Arch) {
        ctxt.symtab()
        ctxt.dodata()
        order := ctxt.address()
-       ctxt.reloc()
        dwarfcompress(ctxt)
+       ctxt.reloc()
        filesize := ctxt.layout(order)
 
        // Write out the output file.