diff options
author | Keith Randall <khr@golang.org> | 2021-05-09 11:06:17 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2021-05-10 13:16:56 +0000 |
commit | 287025925f66f90ad9b30aea2e533928026a8376 (patch) | |
tree | d1d08af3e2dbb39ee461a3d9bc821b406e6a384b /src/cmd | |
parent | c14ecaca8182314efd2ef7280feffc2242644887 (diff) | |
download | go-287025925f66f90ad9b30aea2e533928026a8376.tar.gz go-287025925f66f90ad9b30aea2e533928026a8376.zip |
cmd/compile,reflect: allow longer type names
Encode the length of type names and tags in a varint encoding
instead of a fixed 2-byte encoding. This allows lengths longer
than 65535 (which can happen for large unnamed structs).
Removed the alignment check for #14962, it isn't relevant any more
since we're no longer reading pointers directly out of this data
(it is encoded as an offset which is copied out bytewise).
Fixes #44155
Update #14962
Change-Id: I6084f6027e5955dc16777c87b0dd5ea2baa49629
Reviewed-on: https://go-review.googlesource.com/c/go/+/318249
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/cmd')
-rw-r--r-- | src/cmd/compile/internal/reflectdata/reflect.go | 29 | ||||
-rw-r--r-- | src/cmd/link/internal/ld/decodesym.go | 5 |
2 files changed, 19 insertions, 15 deletions
diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go index 01eaf26a0a..8c0e33f6df 100644 --- a/src/cmd/compile/internal/reflectdata/reflect.go +++ b/src/cmd/compile/internal/reflectdata/reflect.go @@ -5,6 +5,7 @@ package reflectdata import ( + "encoding/binary" "fmt" "internal/buildcfg" "os" @@ -473,21 +474,25 @@ func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int { // dnameData writes the contents of a reflect.name into s at offset ot. func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported bool) int { - if len(name) > 1<<16-1 { - base.Fatalf("name too long: %s", name) + if len(name) >= 1<<29 { + base.Fatalf("name too long: %d %s...", len(name), name[:1024]) } - if len(tag) > 1<<16-1 { - base.Fatalf("tag too long: %s", tag) + if len(tag) >= 1<<29 { + base.Fatalf("tag too long: %d %s...", len(tag), tag[:1024]) } + var nameLen [binary.MaxVarintLen64]byte + nameLenLen := binary.PutUvarint(nameLen[:], uint64(len(name))) + var tagLen [binary.MaxVarintLen64]byte + tagLenLen := binary.PutUvarint(tagLen[:], uint64(len(tag))) // Encode name and tag. See reflect/type.go for details. var bits byte - l := 1 + 2 + len(name) + l := 1 + nameLenLen + len(name) if exported { bits |= 1 << 0 } if len(tag) > 0 { - l += 2 + len(tag) + l += tagLenLen + len(tag) bits |= 1 << 1 } if pkg != nil { @@ -495,14 +500,12 @@ func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported b } b := make([]byte, l) b[0] = bits - b[1] = uint8(len(name) >> 8) - b[2] = uint8(len(name)) - copy(b[3:], name) + copy(b[1:], nameLen[:nameLenLen]) + copy(b[1+nameLenLen:], name) if len(tag) > 0 { - tb := b[3+len(name):] - tb[0] = uint8(len(tag) >> 8) - tb[1] = uint8(len(tag)) - copy(tb[2:], tag) + tb := b[1+nameLenLen+len(name):] + copy(tb, tagLen[:tagLenLen]) + copy(tb[tagLenLen:], tag) } ot = int(s.WriteBytes(base.Ctxt, int64(ot), b)) diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go index fc179fc6e4..c41d97706e 100644 --- a/src/cmd/link/internal/ld/decodesym.go +++ b/src/cmd/link/internal/ld/decodesym.go @@ -10,6 +10,7 @@ import ( "cmd/link/internal/loader" "cmd/link/internal/sym" "debug/elf" + "encoding/binary" "log" ) @@ -126,8 +127,8 @@ func decodetypeName(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs } data := ldr.Data(r) - namelen := int(uint16(data[1])<<8 | uint16(data[2])) - return string(data[3 : 3+namelen]) + nameLen, nameLenLen := binary.Uvarint(data[1:]) + return string(data[1+nameLenLen : 1+nameLenLen+int(nameLen)]) } func decodetypeFuncInType(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym { |