Skip to content

Commit 18fb670

Browse files
committed
cmd/internal/obj: fix LSym.Type during compilation, not linking
Prior to this CL, the compiler and assembler were sloppy about the LSym.Type for LSyms containing static data. The linker then fixed this up, converting Sxxx and SBSS to SDATA, and SNOPTRBSS to SNOPTRDATA if it noticed that the symbol had associated data. It is preferable to just get this right in cmd/compile and cmd/asm, because it removes an unnecessary traversal of the symbol table from the linker (see #14624). Do this by touching up the LSym.Type fixes in LSym.prepwrite and Link.Globl. I have confirmed by instrumenting the linker that the now-eliminated code paths were unreached. And an additional check in the object file writing code will help preserve that invariant. There was a case in the Windows linker, with internal linking and cgo, where we were generating SNOPTRBSS symbols with data. For now, convert those at the site at which they occur into SNOPTRDATA, just like they were. Does not pass toolstash-check, but does generate identical linked binaries. No compiler performance changes. Change-Id: I77b071ab103685ff8e042cee9abb864385488872 Reviewed-on: https://go-review.googlesource.com/40864 Run-TryBot: Josh Bleecher Snyder <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Alex Brainman <[email protected]> Reviewed-by: Michael Hudson-Doyle <[email protected]>
1 parent 00f8277 commit 18fb670

File tree

8 files changed

+42
-24
lines changed

8 files changed

+42
-24
lines changed

src/cmd/compile/internal/gc/obj.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,6 @@ func addGCLocals() {
259259
}
260260

261261
func duintxx(s *obj.LSym, off int, v uint64, wid int) int {
262-
if s.Type == 0 {
263-
// TODO(josharian): Do this in obj.prepwrite instead.
264-
s.Type = objabi.SDATA
265-
}
266262
if off&(wid-1) != 0 {
267263
Fatalf("duintxxLSym: misaligned: v=%d wid=%d off=%d", v, wid, off)
268264
}

src/cmd/internal/obj/data.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,13 @@ func (s *LSym) prepwrite(ctxt *Link, off int64, siz int) {
7373
if off < 0 || siz < 0 || off >= 1<<30 {
7474
ctxt.Diag("prepwrite: bad off=%d siz=%d s=%v", off, siz, s)
7575
}
76-
if s.Type == objabi.SBSS || s.Type == objabi.STLSBSS {
77-
ctxt.Diag("cannot supply data for BSS var")
76+
switch s.Type {
77+
case objabi.Sxxx, objabi.SBSS:
78+
s.Type = objabi.SDATA
79+
case objabi.SNOPTRBSS:
80+
s.Type = objabi.SNOPTRDATA
81+
case objabi.STLSBSS:
82+
ctxt.Diag("cannot supply data for %v var %v", s.Type, s.Name)
7883
}
7984
l := off + int64(siz)
8085
s.Grow(l)

src/cmd/internal/obj/objfile.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ func WriteObjFile(ctxt *Link, b *bufio.Writer) {
128128
}
129129
}
130130
for _, s := range ctxt.Data {
131+
if len(s.P) > 0 {
132+
switch s.Type {
133+
case objabi.SBSS, objabi.SNOPTRBSS, objabi.STLSBSS:
134+
ctxt.Diag("cannot provide data for %v sym %v", s.Type, s.Name)
135+
}
136+
}
131137
w.wr.Write(s.P)
132138
}
133139

src/cmd/internal/obj/plist.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,11 @@ func (ctxt *Link) Globl(s *LSym, size int64, flag int) {
171171
if flag&RODATA != 0 {
172172
s.Type = objabi.SRODATA
173173
} else if flag&NOPTR != 0 {
174-
s.Type = objabi.SNOPTRBSS
174+
if s.Type == objabi.SDATA {
175+
s.Type = objabi.SNOPTRDATA
176+
} else {
177+
s.Type = objabi.SNOPTRBSS
178+
}
175179
} else if flag&TLSBSS != 0 {
176180
s.Type = objabi.STLSBSS
177181
}

src/cmd/link/internal/ld/data.go

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,21 +1141,16 @@ func addinitarrdata(ctxt *Link, s *Symbol) {
11411141
}
11421142

11431143
func dosymtype(ctxt *Link) {
1144-
for _, s := range ctxt.Syms.Allsym {
1145-
if len(s.P) > 0 {
1146-
if s.Type == SBSS {
1147-
s.Type = SDATA
1148-
}
1149-
if s.Type == SNOPTRBSS {
1150-
s.Type = SNOPTRDATA
1151-
}
1152-
}
1153-
// Create a new entry in the .init_array section that points to the
1154-
// library initializer function.
1155-
switch Buildmode {
1156-
case BuildmodeCArchive, BuildmodeCShared:
1157-
if s.Name == *flagEntrySymbol {
1158-
addinitarrdata(ctxt, s)
1144+
switch Buildmode {
1145+
case BuildmodeCArchive, BuildmodeCShared:
1146+
for _, s := range ctxt.Syms.Allsym {
1147+
// Create a new entry in the .init_array section that points to the
1148+
// library initializer function.
1149+
switch Buildmode {
1150+
case BuildmodeCArchive, BuildmodeCShared:
1151+
if s.Name == *flagEntrySymbol {
1152+
addinitarrdata(ctxt, s)
1153+
}
11591154
}
11601155
}
11611156
}

src/cmd/link/internal/ld/ldpe.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
177177

178178
case IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.bss
179179
s.Type = SNOPTRBSS
180+
// It seems like this shouldn't happen, but it does, with symbol "runtime/cgo(.bss)".
181+
// TODO: Figure out why and either document why it is ok or fix it at the source--
182+
// either by eliminating the all-zero data or
183+
// by making this SNOPTRDATA (IMAGE_SCN_CNT_INITIALIZED_DATA) to begin with.
184+
if len(data) > 0 {
185+
for _, x := range data {
186+
if x != 0 {
187+
Errorf(s, "non-zero data in .bss section: %q", data)
188+
}
189+
}
190+
s.Type = SNOPTRDATA
191+
}
180192

181193
case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.data
182194
s.Type = SNOPTRDATA

src/cmd/link/internal/ld/lib.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,7 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
19431943
continue
19441944
}
19451945
if len(s.P) > 0 {
1946-
Errorf(s, "should not be bss (size=%d type=%d special=%v)", len(s.P), s.Type, s.Attr.Special())
1946+
Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special())
19471947
}
19481948
put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
19491949

src/debug/pe/file_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ func testDWARF(t *testing.T, linktype int) {
341341
args = append(args, src)
342342
out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput()
343343
if err != nil {
344-
t.Fatalf("building test executable failed: %s %s", err, out)
344+
t.Fatalf("building test executable for linktype %d failed: %s %s", linktype, err, out)
345345
}
346346
out, err = exec.Command(exe).CombinedOutput()
347347
if err != nil {

0 commit comments

Comments
 (0)