From d704bb0dc907d32ca827e97bf506794d809ebce8 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Sat, 11 Oct 2014 22:01:04 +1100 Subject: [PATCH] cmd/ld: do not assume that only pe section names start with '.' Our current pe object reader assumes that every symbol starting with '.' is section. It appeared to be true, until now gcc 4.9.1 generates some symbols with '.' at the front. Change that logic to check other symbol fields in addition to checking for '.'. I am not an expert here, but it seems reasonable to me. Added test, but it is only good, if tested with gcc 4.9.1. Otherwise the test PASSes regardless. Fixes #8811. Fixes #8856. LGTM=jfrederich, iant, stephen.gutekanst R=golang-codereviews, jfrederich, stephen.gutekanst, iant CC=alex.brainman, golang-codereviews https://golang.org/cl/152410043 --- misc/cgo/test/cgo_test.go | 1 + misc/cgo/test/issue8811.c | 8 ++++++++ misc/cgo/test/issue8811.go | 22 ++++++++++++++++++++++ src/cmd/ld/ldpe.c | 17 ++++++++++++----- 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 misc/cgo/test/issue8811.c create mode 100644 misc/cgo/test/issue8811.go diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go index 05deb4197c1d0a..3b289ba7b50539 100644 --- a/misc/cgo/test/cgo_test.go +++ b/misc/cgo/test/cgo_test.go @@ -59,6 +59,7 @@ func Test8092(t *testing.T) { test8092(t) } func Test7978(t *testing.T) { test7978(t) } func Test8694(t *testing.T) { test8694(t) } func Test8517(t *testing.T) { test8517(t) } +func Test8811(t *testing.T) { test8811(t) } func TestReturnAfterGrow(t *testing.T) { testReturnAfterGrow(t) } func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) } diff --git a/misc/cgo/test/issue8811.c b/misc/cgo/test/issue8811.c new file mode 100644 index 00000000000000..584bb39342e4df --- /dev/null +++ b/misc/cgo/test/issue8811.c @@ -0,0 +1,8 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +int issue8811Initialized = 0; + +void issue8811Init() { +} diff --git a/misc/cgo/test/issue8811.go b/misc/cgo/test/issue8811.go new file mode 100644 index 00000000000000..2e217d9356ad3b --- /dev/null +++ b/misc/cgo/test/issue8811.go @@ -0,0 +1,22 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotest + +/* +extern int issue8811Initialized; +extern void issue8811Init(); + +void issue8811Execute() { + if(!issue8811Initialized) + issue8811Init(); +} +*/ +import "C" + +import "testing" + +func test8811(t *testing.T) { + C.issue8811Execute() +} diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c index 9257c243c94b34..4f5e51f2f1b557 100644 --- a/src/cmd/ld/ldpe.c +++ b/src/cmd/ld/ldpe.c @@ -128,6 +128,7 @@ struct PeObj { }; static int map(PeObj *obj, PeSect *sect); +static int issect(PeSym *s); static int readsym(PeObj *obj, int i, PeSym **sym); void @@ -318,8 +319,8 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) // ld -r could generate multiple section symbols for the // same section but with different values, we have to take // that into account - if (obj->pesym[symindex].name[0] == '.') - rp->add += obj->pesym[symindex].value; + if(issect(&obj->pesym[symindex])) + rp->add += obj->pesym[symindex].value; } qsort(r, rsect->sh.NumberOfRelocations, sizeof r[0], rbyoff); @@ -327,12 +328,12 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) s->r = r; s->nr = rsect->sh.NumberOfRelocations; } - + // enter sub-symbols into symbol table. for(i=0; inpesym; i++) { if(obj->pesym[i].name == 0) continue; - if(obj->pesym[i].name[0] == '.') //skip section + if(issect(&obj->pesym[i])) continue; if(obj->pesym[i].sectnum > 0) { sect = &obj->sect[obj->pesym[i].sectnum-1]; @@ -430,6 +431,12 @@ map(PeObj *obj, PeSect *sect) return 0; } +static int +issect(PeSym *s) +{ + return s->sclass == IMAGE_SYM_CLASS_STATIC && s->type == 0 && s->name[0] == '.'; +} + static int readsym(PeObj *obj, int i, PeSym **y) { @@ -445,7 +452,7 @@ readsym(PeObj *obj, int i, PeSym **y) sym = &obj->pesym[i]; *y = sym; - if(sym->name[0] == '.') // .section + if(issect(sym)) name = obj->sect[sym->sectnum-1].sym->name; else { name = sym->name;