]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: apply R_DWARFFILEREF later
authorCherry Zhang <cherryyz@google.com>
Thu, 4 Apr 2019 04:30:25 +0000 (00:30 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 19 Apr 2019 18:25:09 +0000 (18:25 +0000)
Apply R_DWARFFILEREF relocations later, along with other
relocations, so that we don't modify symbols' contents before
they are written to the output buffer.

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

Change-Id: I8e9ffb2f05acf8f198589b8770f277beb3847541
Reviewed-on: https://go-review.googlesource.com/c/go/+/170740
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

index a6f75b74e1f43d49f5ed7c562f811588744593b6..04fe3cb3b5283fafc455a4d800729377f5e74668 100644 (file)
@@ -168,12 +168,6 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
                if r.Siz == 0 { // informational relocation - no work to do
                        continue
                }
-               if r.Type == objabi.R_DWARFFILEREF {
-                       // These should have been processed previously during
-                       // line table writing.
-                       Errorf(s, "orphan R_DWARFFILEREF reloc to %v", r.Sym.Name)
-                       continue
-               }
 
                // We need to be able to reference dynimport symbols when linking against
                // shared libraries, and Solaris, Darwin and AIX need it always
@@ -490,6 +484,10 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
                        // This isn't a real relocation so it must not update
                        // its offset value.
                        continue
+
+               case objabi.R_DWARFFILEREF:
+                       // The final file index is saved in r.Add in dwarf.go:writelines.
+                       o = r.Add
                }
 
                if r.Variant != sym.RV_NONE {
index 0d159c76585f09547c020863d787dcd06136aff6..9e7fea0101125d3007d46661b8d96e96a77aee49 100644 (file)
@@ -1302,7 +1302,7 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
                ls.SetUint32(ctxt.Arch, headerLengthOffset, uint32(headerend-headerstart))
        }
 
-       // Apply any R_DWARFFILEREF relocations, since we now know the
+       // Process any R_DWARFFILEREF relocations, since we now know the
        // line table file indices for this compilation unit. Note that
        // this loop visits only subprogram DIEs: if the compiler is
        // changed to generate DW_AT_decl_file attributes for other
@@ -1315,8 +1315,6 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
                        if r.Type != objabi.R_DWARFFILEREF {
                                continue
                        }
-                       // Mark relocation as applied (signal to relocsym)
-                       r.Done = true
                        idx, ok := fileNums[int(r.Sym.Value)]
                        if ok {
                                if int(int32(idx)) != idx {
@@ -1329,7 +1327,11 @@ func writelines(ctxt *Link, unit *compilationUnit, ls *sym.Symbol) {
                                        Errorf(f, "bad R_DWARFFILEREF relocation offset %d + 4 would write past length %d", r.Off, len(s.P))
                                        continue
                                }
-                               ctxt.Arch.ByteOrder.PutUint32(f.P[r.Off:r.Off+4], uint32(idx))
+                               if r.Add != 0 {
+                                       Errorf(f, "bad R_DWARFFILEREF relocation: addend not zero")
+                               }
+                               r.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
+                               r.Add = int64(idx) // record the index in r.Add, we'll apply it in the reloc phase.
                        } else {
                                _, found := missing[int(r.Sym.Value)]
                                if !found {