Skip to content

Commit

Permalink
debug/elf: handle sections with non-zero addresses when applying relo…
Browse files Browse the repository at this point in the history
…cations

commit 72ec930 added basic support for
relocations, but assumed that the symbol value would be 0, likely because
.debug_info always has address == 0 in the ELF section headers.

commit df855da added further support
for relocations, but explicitly encoded the original assumption that
section addresses would be 0.

This commit removes that assumption, and adds support for relocations
relative to sections that have non-zero addresses.
Typically, sections that are part of a LOAD program segment are such
sections. For example, .debug_ranges relocations could be relative to
.text, which usually has an address > 0.

This addresses golang#40879, causing
relocations for .debug_ranges to be incorrectly applied.
  • Loading branch information
vikmik committed Aug 25, 2020
1 parent 3d77461 commit 4b89dec
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 24 deletions.
11 changes: 4 additions & 7 deletions src/debug/elf/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,17 +630,14 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {

// relocSymbolTargetOK decides whether we should try to apply a
// relocation to a DWARF data section, given a pointer to the symbol
// targeted by the relocation. Most relocations in DWARF data tend to
// be section-relative, but some target non-section symbols (for
// example, low_PC attrs on subprogram or compilation unit DIEs that
// target function symbols), and we need to include these as well.
// targeted by the relocation.
// Note: most relocations in DWARF data tend to be section-relative,
// but some target non-section symbols (for example, low_PC attrs on
// subprogram or compilation unit DIEs that target function symbols).
// Return value is a pair (X,Y) where X is a boolean indicating
// whether the relocation is needed, and Y is the symbol value in the
// case of a non-section relocation that needs to be applied.
func relocSymbolTargetOK(sym *Symbol) (bool, uint64) {
if ST_TYPE(sym.Info) == STT_SECTION {
return true, 0
}
if sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE {
return true, sym.Value
}
Expand Down
90 changes: 73 additions & 17 deletions src/debug/elf/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ func decompress(gz string) (io.ReaderAt, error) {
type relocationTestEntry struct {
entryNumber int
entry *dwarf.Entry
pcRanges [][2]uint64
}

type relocationTest struct {
Expand All @@ -317,7 +318,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -336,7 +337,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -355,7 +356,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -374,7 +375,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -393,7 +394,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -412,7 +413,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrHighpc, Val: int64(48), Class: dwarf.ClassConstant},
},
}},
}, nil},
},
},
{
Expand All @@ -431,7 +432,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -450,7 +451,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -469,7 +470,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -488,7 +489,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: int64(58), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -507,7 +508,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -526,7 +527,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -545,7 +546,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -564,7 +565,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -583,7 +584,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}},
}, nil},
},
},
{
Expand All @@ -600,7 +601,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
{Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
},
}},
}, nil},
},
},
{
Expand All @@ -617,7 +618,7 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
{Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc},
},
}},
}, nil},
{204, &dwarf.Entry{
Offset: 0xc70,
Tag: dwarf.TagMember,
Expand All @@ -629,6 +630,50 @@ var relocationTests = []relocationTest{
{Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
{Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc},
},
}, nil},
},
},
{
"testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64",
[]relocationTestEntry{
{0, &dwarf.Entry{
Offset: 0xb,
Tag: dwarf.TagCompileUnit,
Children: true,
Field: []dwarf.Field{
{Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables", Class: dwarf.ClassString},
{Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
{Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
{Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
{Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}, [][2]uint64{
{0x1125, 0x1137},
{0xc0ffee, 0xc0fff9},
}},
},
},
{
"testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64",
[]relocationTestEntry{
{0, &dwarf.Entry{
Offset: 0xb,
Tag: dwarf.TagCompileUnit,
Children: true,
Field: []dwarf.Field{
{Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables", Class: dwarf.ClassString},
{Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
{Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
{Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
{Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
{Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
},
}, [][2]uint64{
{0x1125, 0x1137},
{0xc0ffee, 0xc0fff9},
}},
},
},
Expand Down Expand Up @@ -664,6 +709,17 @@ func TestDWARFRelocations(t *testing.T) {
t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
continue
}
if testEntry.pcRanges != nil {
pcRanges, err := dwarf.Ranges(entry)
if err != nil {
t.Error(err)
continue
}
if !reflect.DeepEqual(testEntry.pcRanges, pcRanges) {
t.Errorf("#%d/%d: PC range mismatch: got:%#v want:%#v", i, testEntry.entryNumber, pcRanges, testEntry.pcRanges)
continue
}
}
}
}
}
Expand Down
Binary file not shown.
Binary file not shown.
11 changes: 11 additions & 0 deletions src/debug/elf/testdata/multiple-code-sections.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Build with:
// gcc -g multiple-code-sections.c multiple-code-sections.ld -Wl,--emit-relocs -Wl,--discard-none -o go-relocation-test-gcc930-ranges-with-rela-x86-64
// gcc -g multiple-code-sections.c multiple-code-sections.ld -o go-relocation-test-gcc930-ranges-no-rela-x86-64
__attribute__((section(".coffee_section")))
int coffee(void) {
return 0;
}

int main(int argc, char *argv[]) {
return 0;
}
5 changes: 5 additions & 0 deletions src/debug/elf/testdata/multiple-code-sections.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SECTIONS
{
. = 0xC0FFEE;
.coffee_section : {}
}

0 comments on commit 4b89dec

Please sign in to comment.