From 0e06775eebf6d357f604a55c803aab5cc8054e67 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Fri, 13 Mar 2020 11:43:35 -0400 Subject: [PATCH] [dev.link] cmd/link: don't truncate external relocation type 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 TryBot-Result: Gobot Gobot Reviewed-by: Than McIntosh --- src/cmd/link/internal/loader/loader.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 8eb12c5941..95d2ac8a7f 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -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 -- 2.48.1