Skip to content

Commit 7668984

Browse files
author
Joel Sing
committed
debug/elf: do not skip first symbol in the symbol table
Do not skip the first symbol in the symbol table. Any other indexes into the symbol table (for example, indexes in relocation entries) will now refer to the symbol following the one that was intended. Add an object that contains debug relocations, which debug/dwarf failed to decode correctly. Extend the relocation tests to cover this case. Note that the existing tests passed since the symbol following the symbol that required relocation is also of type STT_SECTION. Fixes #4107. R=golang-dev, mikioh.mikioh, iant, iant CC=golang-dev https://golang.org/cl/6848044
1 parent 063c13a commit 7668984

File tree

4 files changed

+51
-27
lines changed

4 files changed

+51
-27
lines changed

doc/go1.1.html

+10
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,14 @@ <h3 id="asm">Assembler</h3>
6262

6363
<h2 id="library">Changes to the standard library</h2>
6464

65+
<h3 id="debug/elf">debug/elf</h3>
66+
<p>
67+
Previous versions of the debug/elf package intentionally skipped over the first
68+
symbol in the ELF symbol table, since it is always an empty symbol. This symbol
69+
is no longer skipped since indexes into the symbol table returned by debug/elf,
70+
will be different to indexes into the original ELF symbol table. Any code that
71+
calls the debug/elf functions Symbols or ImportedSymbols may need to be
72+
adjusted to account for the additional symbol and the change in symbol offsets.
73+
</p>
74+
6575
TODO

src/pkg/debug/elf/file.go

-8
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,6 @@ func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
417417
return nil, nil, errors.New("cannot load string table section")
418418
}
419419

420-
// The first entry is all zeros.
421-
var skip [Sym32Size]byte
422-
symtab.Read(skip[0:])
423-
424420
symbols := make([]Symbol, symtab.Len()/Sym32Size)
425421

426422
i := 0
@@ -460,10 +456,6 @@ func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
460456
return nil, nil, errors.New("cannot load string table section")
461457
}
462458

463-
// The first entry is all zeros.
464-
var skip [Sym64Size]byte
465-
symtab.Read(skip[0:])
466-
467459
symbols := make([]Symbol, symtab.Len()/Sym64Size)
468460

469461
i := 0

src/pkg/debug/elf/file_test.go

+41-19
Original file line numberDiff line numberDiff line change
@@ -175,23 +175,41 @@ func TestOpen(t *testing.T) {
175175
}
176176
}
177177

178+
type relocationTestEntry struct {
179+
entryNumber int
180+
entry *dwarf.Entry
181+
}
182+
178183
type relocationTest struct {
179-
file string
180-
firstEntry *dwarf.Entry
184+
file string
185+
entries []relocationTestEntry
181186
}
182187

183188
var relocationTests = []relocationTest{
184189
{
185190
"testdata/go-relocation-test-gcc441-x86-64.obj",
186-
&dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
191+
[]relocationTestEntry{
192+
{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
193+
},
187194
},
188195
{
189196
"testdata/go-relocation-test-gcc441-x86.obj",
190-
&dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
197+
[]relocationTestEntry{
198+
{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
199+
},
191200
},
192201
{
193202
"testdata/go-relocation-test-gcc424-x86-64.obj",
194-
&dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
203+
[]relocationTestEntry{
204+
{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
205+
},
206+
},
207+
{
208+
"testdata/gcc-amd64-openbsd-debug-with-rela.obj",
209+
[]relocationTestEntry{
210+
{203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}}}},
211+
{204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(237)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}}}}},
212+
},
195213
},
196214
}
197215

@@ -207,20 +225,24 @@ func TestDWARFRelocations(t *testing.T) {
207225
t.Error(err)
208226
continue
209227
}
210-
reader := dwarf.Reader()
211-
// Checking only the first entry is sufficient since it has
212-
// many different strings. If the relocation had failed, all
213-
// the string offsets would be zero and all the strings would
214-
// end up being the same.
215-
firstEntry, err := reader.Next()
216-
if err != nil {
217-
t.Error(err)
218-
continue
219-
}
220-
221-
if !reflect.DeepEqual(test.firstEntry, firstEntry) {
222-
t.Errorf("#%d: mismatch: got:%#v want:%#v", i, firstEntry, test.firstEntry)
223-
continue
228+
for _, testEntry := range test.entries {
229+
reader := dwarf.Reader()
230+
for j := 0; j < testEntry.entryNumber; j++ {
231+
entry, err := reader.Next()
232+
if entry == nil || err != nil {
233+
t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
234+
continue
235+
}
236+
}
237+
entry, err := reader.Next()
238+
if err != nil {
239+
t.Error(err)
240+
continue
241+
}
242+
if !reflect.DeepEqual(testEntry.entry, entry) {
243+
t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
244+
continue
245+
}
224246
}
225247
}
226248
}
Binary file not shown.

0 commit comments

Comments
 (0)