]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: don't truncate external relocation type
authorCherry Zhang <cherryyz@google.com>
Fri, 13 Mar 2020 15:43:35 +0000 (11:43 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 13 Mar 2020 19:28:06 +0000 (19:28 +0000)
In CL 222244, we store external relocations in the same format as
Go object files. In Go object file format, the relocation type is
a uint8. However, for external relocations the type may not
always fit in a uint8. Truncating it will result in a bad
relocation. Fix this by storing the external reloc type on the
side. (An alternative is to extend the Go object file format to
use a uint16, but it is not necessary for Go relocations and
will waste some binary size.)

Fix ARM build.

Change-Id: I343e240d38ee0e2cc91e0e7754d03b19b525a014
Reviewed-on: https://go-review.googlesource.com/c/go/+/223338
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/loader/loader.go

index 8eb12c594158abe867ec09ae31d2d86613799f03..95d2ac8a7f5ccda61947bdf0a8eaed169c2b0ab7 100644 (file)
@@ -55,9 +55,16 @@ type Reloc2 struct {
        *goobj2.Reloc2
        r *oReader
        l *Loader
+
+       // External reloc types may not fit into a uint8 which the Go object file uses.
+       // Store it here, instead of in the byte of goobj2.Reloc2.
+       // For Go symbols this will always be 0.
+       // goobj2.Reloc2.Type() + typ is always the right type, for both Go and external
+       // symbols.
+       typ objabi.RelocType
 }
 
-func (rel Reloc2) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc2.Type()) }
+func (rel Reloc2) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc2.Type()) + rel.typ }
 func (rel Reloc2) Sym() Sym               { return rel.l.resolve(rel.r, rel.Reloc2.Sym()) }
 
 // oReader is a wrapper type of obj.Reader, along with some
@@ -1463,10 +1470,10 @@ func (relocs *Relocs) At2(j int) Reloc2 {
                // Ugly. Maybe we just want to use this format to store the
                // reloc record in the first place?
                var b goobj2.Reloc2
-               b.Set(r.Off, r.Size, uint8(r.Type), r.Add, goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(r.Sym)})
-               return Reloc2{&b, relocs.r, relocs.l}
+               b.Set(r.Off, r.Size, 0, r.Add, goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(r.Sym)})
+               return Reloc2{&b, relocs.r, relocs.l, r.Type}
        }
-       return Reloc2{relocs.r.Reloc2(relocs.li, j), relocs.r, relocs.l}
+       return Reloc2{relocs.r.Reloc2(relocs.li, j), relocs.r, relocs.l, 0}
 }
 
 // ReadAll method reads all relocations for a symbol into the