diff options
| author | Keith Randall <khr@golang.org> | 2014-12-19 20:44:18 -0800 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2014-12-22 22:25:48 +0000 |
| commit | fbc56cf05015899aba236d5a68096a770de3ad0a (patch) | |
| tree | 44d489f2452644d208643db8fc19fe566b15a409 /src/cmd/ld | |
| parent | aaa4bf3720bbf69e1ac65414448baf88b5e4cd83 (diff) | |
| download | go-fbc56cf05015899aba236d5a68096a770de3ad0a.tar.xz | |
runtime: hashmap: move overflow pointer to end of bucket
Pointers to zero-sized values may end up pointing to the next
object in memory, and possibly off the end of a span. This
can cause memory leaks and/or confuse the garbage collector.
By putting the overflow pointer at the end of the bucket, we
make sure that pointers to any zero-sized keys or values don't
accidentally point to the next object in memory.
fixes #9384
Change-Id: I5d434df176984cb0210b4d0195dd106d6eb28f73
Reviewed-on: https://go-review.googlesource.com/1869
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/cmd/ld')
| -rw-r--r-- | src/cmd/ld/dwarf.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c index fbb5699bdb..b5331e829f 100644 --- a/src/cmd/ld/dwarf.c +++ b/src/cmd/ld/dwarf.c @@ -1281,12 +1281,19 @@ synthesizemaptypes(DWDie *die) fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys"); newrefattr(fld, DW_AT_type, dwhk); - newmemberoffsetattr(fld, BucketSize + PtrSize); + newmemberoffsetattr(fld, BucketSize); fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values"); newrefattr(fld, DW_AT_type, dwhv); - newmemberoffsetattr(fld, BucketSize + PtrSize + BucketSize * keysize); - newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize + PtrSize + BucketSize * keysize + BucketSize * valsize, 0); - substitutetype(dwhb, "overflow", defptrto(dwhb)); + newmemberoffsetattr(fld, BucketSize + BucketSize * keysize); + fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow"); + newrefattr(fld, DW_AT_type, defptrto(dwhb)); + newmemberoffsetattr(fld, BucketSize + BucketSize * (keysize + valsize)); + if(RegSize > PtrSize) { + fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad"); + newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")); + newmemberoffsetattr(fld, BucketSize + BucketSize * (keysize + valsize) + PtrSize); + } + newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize + BucketSize * keysize + BucketSize * valsize + RegSize, 0); // Construct hash<K,V> dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, |
