NumberOfLineNumbers: sh.NumberOfLineNumbers,
Characteristics: sh.Characteristics,
}
- s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
+ r2 := r
+ if sh.PointerToRawData == 0 { // .bss must have all 0s
+ r2 = zeroReaderAt{}
+ }
+ s.sr = io.NewSectionReader(r2, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
s.ReaderAt = s.sr
f.Sections[i] = s
}
return f, nil
}
+// zeroReaderAt is ReaderAt that reads 0s.
+type zeroReaderAt struct{}
+
+// ReadAt writes len(p) 0s into p.
+func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
+ for i := range p {
+ p[i] = 0
+ }
+ return len(p), nil
+}
+
// getString extracts a string from symbol string table.
func getString(section []byte, start int) (string, bool) {
if start < 0 || start >= len(section) {
import (
"debug/dwarf"
+ "internal/testenv"
"io/ioutil"
"os"
"os/exec"
}
t.Fatal("main.main not found")
}
+
+func TestBSSHasZeros(t *testing.T) {
+ testenv.MustHaveExec(t)
+
+ if runtime.GOOS != "windows" {
+ t.Skip("skipping windows only test")
+ }
+ gccpath, err := exec.LookPath("gcc")
+ if err != nil {
+ t.Skip("skipping test: gcc is missing")
+ }
+
+ tmpdir, err := ioutil.TempDir("", "TestBSSHasZeros")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tmpdir)
+
+ srcpath := filepath.Join(tmpdir, "a.c")
+ src := `
+#include <stdio.h>
+
+int zero = 0;
+
+int
+main(void)
+{
+ printf("%d\n", zero);
+ return 0;
+}
+`
+ err = ioutil.WriteFile(srcpath, []byte(src), 0644)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ objpath := filepath.Join(tmpdir, "a.obj")
+ cmd := exec.Command(gccpath, "-c", srcpath, "-o", objpath)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("failed to build object file: %v - %v", err, string(out))
+ }
+
+ f, err := Open(objpath)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer f.Close()
+
+ var bss *Section
+ for _, sect := range f.Sections {
+ if sect.Name == ".bss" {
+ bss = sect
+ break
+ }
+ }
+ if bss == nil {
+ t.Fatal("could not find .bss section")
+ }
+ data, err := bss.Data()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data) == 0 {
+ t.Fatalf("%s file .bss section cannot be empty", objpath)
+ }
+ for _, b := range data {
+ if b != 0 {
+ t.Fatalf(".bss section has non zero bytes: %v", data)
+ }
+ }
+}