Skip to content

Commit

Permalink
cmd/ld: do not assume that only pe section names start with '.'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
alexbrainman committed Oct 11, 2014
1 parent d0ee959 commit d704bb0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 5 deletions.
1 change: 1 addition & 0 deletions misc/cgo/test/cgo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) }

Expand Down
8 changes: 8 additions & 0 deletions misc/cgo/test/issue8811.c
Original file line number Diff line number Diff line change
@@ -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() {
}
22 changes: 22 additions & 0 deletions misc/cgo/test/issue8811.go
Original file line number Diff line number Diff line change
@@ -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()
}
17 changes: 12 additions & 5 deletions src/cmd/ld/ldpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -318,21 +319,21 @@ 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);

s = rsect->sym;
s->r = r;
s->nr = rsect->sh.NumberOfRelocations;
}

// enter sub-symbols into symbol table.
for(i=0; i<obj->npesym; 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];
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down

0 comments on commit d704bb0

Please sign in to comment.