Skip to content

Commit

Permalink
cmd/internal/goobj: fix buglet in object file reader
Browse files Browse the repository at this point in the history
The code in the new (introduced in 1.15) Go object file reader was
casting a pointer-mmaped-memory into a large array prior to performing
a read of the relocations section:

	return (*[1<<20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]

For very large object files, this artificial array isn't large enough
(that is, there are more than 1048576 relocs to read), so update the
code to use a larger artifical array size.

Fixes #41621.

Change-Id: Ic047c8aef4f8a3839f2e7e3594bce652ebd6bd5b
Reviewed-on: https://go-review.googlesource.com/c/go/+/278492
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Trust: Than McIntosh <thanm@google.com>
  • Loading branch information
thanm committed Dec 16, 2020
1 parent 75e16f5 commit f4e7a6b
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/cmd/internal/goobj/objfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,11 @@ func (r *RefFlags) SetFlag2(x uint8) { r[9] = x }

func (r *RefFlags) Write(w *Writer) { w.Bytes(r[:]) }

// Used to construct an artifically large array type when reading an
// item from the object file relocs section or aux sym section (needs
// to work on 32-bit as well as 64-bit). See issue 41621.
const huge = (1<<31 - 1) / RelocSize

// Referenced symbol name.
//
// Serialized format:
Expand Down Expand Up @@ -792,7 +797,7 @@ func (r *Reader) Reloc(i uint32, j int) *Reloc {
func (r *Reader) Relocs(i uint32) []Reloc {
off := r.RelocOff(i, 0)
n := r.NReloc(i)
return (*[1 << 20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
return (*[huge]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
}

// NAux returns the number of aux symbols of the i-th symbol.
Expand All @@ -818,7 +823,7 @@ func (r *Reader) Aux(i uint32, j int) *Aux {
func (r *Reader) Auxs(i uint32) []Aux {
off := r.AuxOff(i, 0)
n := r.NAux(i)
return (*[1 << 20]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
return (*[huge]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
}

// DataOff returns the offset of the i-th symbol's data.
Expand Down

0 comments on commit f4e7a6b

Please sign in to comment.