From a9503c50b327ba5eb453a1b983d3a733fadc2735 Mon Sep 17 00:00:00 2001 From: Victor Michel Date: Wed, 19 Aug 2020 00:22:42 -0700 Subject: [PATCH] Add code --- .gitignore | 1 + Makefile | 14 ++++++++++++++ README.md | 10 ++++++++++ main.go | 38 ++++++++++++++++++++++++++++++++++++++ test.sh | 9 +++++++++ testdata/.gitignore | 1 + testdata/Makefile | 7 +++++++ testdata/repro.c | 8 ++++++++ testdata/repro.ld | 5 +++++ 9 files changed, 93 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 main.go create mode 100755 test.sh create mode 100644 testdata/.gitignore create mode 100644 testdata/Makefile create mode 100644 testdata/repro.c create mode 100644 testdata/repro.ld diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c7a225 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dwarf-relocation-golang-bug diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4daffd4 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +.PHONY: all test + +all: test + +testdata/repro: + cd testdata && make + +dwarf-relocation-golang-bug: main.go + go build + +test: testdata/repro dwarf-relocation-golang-bug + @echo + @echo "Running test" + @./test.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..8f312d0 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +This is a standalone repro case for https://github.com/golang/go/issues/40879 + +* `testdata` contains logic to build an executable `testdata/repro` that: + * has a `.rela.debug_ranges` section + * has a DWARF DIE that uses DW_AT_ranges (to force this, I used a linker script to spread the code across 2 sections at different addresses) +* `main.go` contains logic that prints the PC ranges of `testdata/repro` +* `test.sh` will print the PC ranges using both the Go binary, and `llvm-dwarfdump`, to highlight the difference +* `make` will compile all binaries and run `test.sh` + +Note: you need `llvm` installed (for `llvm-dwarfdump`). Alternatively you can change the test.sh script to use the regular `dwarfdump`. diff --git a/main.go b/main.go new file mode 100644 index 0000000..d5c49ae --- /dev/null +++ b/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "debug/elf" + "fmt" + "log" +) + +func main() { + file, err := elf.Open("testdata/repro") + if err != nil { + log.Fatal(err) + } + defer file.Close() + + dw, err := file.DWARF() + if err != nil { + log.Fatal(err) + } + + reader := dw.Reader() + + // The first entry will be the (only) CU + entry, err := reader.Next() + if err != nil { + log.Fatal(err) + } + + // Read PC ranges from DIE + ranges, err := dw.Ranges(entry) + if err != nil { + log.Fatal(err) + } + + for i := range ranges { + fmt.Printf("[0x%x, 0x%x)\n", ranges[i][0], ranges[i][1]) + } +} diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..8fc2e99 --- /dev/null +++ b/test.sh @@ -0,0 +1,9 @@ +#!/bin/bash -eu + +echo "Actual ranges:" +llvm-dwarfdump testdata/repro --name=repro.c | grep -A2 DW_AT_ranges | tail -2 | sed 's/))/)/' | tr -d ' ' + +echo +echo "Ranges derived from Golang's debug/elf + debug/dwarf" +./dwarf-relocation-golang-bug + diff --git a/testdata/.gitignore b/testdata/.gitignore new file mode 100644 index 0000000..de86576 --- /dev/null +++ b/testdata/.gitignore @@ -0,0 +1 @@ +repro diff --git a/testdata/Makefile b/testdata/Makefile new file mode 100644 index 0000000..70589e3 --- /dev/null +++ b/testdata/Makefile @@ -0,0 +1,7 @@ +.PHONY: all + +repro: repro.c repro.ld +# The following command will likely print a warning (about a missing -T option), which should be ignored. +# Removing the warning would require passing a fully-fledged linker script to bypass gcc's default. + gcc -g $^ -Wl,--emit-relocs -o $@ + diff --git a/testdata/repro.c b/testdata/repro.c new file mode 100644 index 0000000..f16e299 --- /dev/null +++ b/testdata/repro.c @@ -0,0 +1,8 @@ +__attribute__((section(".coffee_section"))) +int coffee(void) { + return 0; +} + +int main(int argc, char *argv[]) { + return 0; +} diff --git a/testdata/repro.ld b/testdata/repro.ld new file mode 100644 index 0000000..670456e --- /dev/null +++ b/testdata/repro.ld @@ -0,0 +1,5 @@ +SECTIONS +{ + . = 0xC0FFEE; + .coffee_section : {} +}