aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2014-12-19 20:44:18 -0800
committerKeith Randall <khr@golang.org>2014-12-22 22:25:48 +0000
commitfbc56cf05015899aba236d5a68096a770de3ad0a (patch)
tree44d489f2452644d208643db8fc19fe566b15a409 /src/cmd/ld
parentaaa4bf3720bbf69e1ac65414448baf88b5e4cd83 (diff)
downloadgo-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.c15
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,