aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2021-10-04 19:06:34 +0200
committerDmitry Vyukov <dvyukov@google.com>2021-10-05 14:22:22 +0200
commit477d9f8dc089b54271fc4418c66cda418c9f25ff (patch)
treeb6058fe58383b61ac0ce38e3dab8451325f36461 /pkg
parentb198f94f773ecd05ac863bc43f51632430f52193 (diff)
pkg/cover: workaround clang/ubsan bug
We used to compile and link with a single compiler invocation, but clang has a bug that it tries to link in ubsan runtime when -fsanitize-coverage=trace-pc is provided during linking and ubsan runtime is missing for arm/arm64/riscv arches in the llvm packages. So we first compile with -fsanitize-coverage and then link w/o it.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cover/report_test.go51
1 files changed, 43 insertions, 8 deletions
diff --git a/pkg/cover/report_test.go b/pkg/cover/report_test.go
index 68f7299bc..298086530 100644
--- a/pkg/cover/report_test.go
+++ b/pkg/cover/report_test.go
@@ -33,6 +33,7 @@ import (
type Test struct {
Name string
CFlags []string
+ LDFlags []string
Progs []Prog
AddCover bool
Result string
@@ -72,8 +73,8 @@ func TestReportGenerator(t *testing.T) {
{
Name: "good-pie",
AddCover: true,
- CFlags: []string{"-fsanitize-coverage=trace-pc", "-g", "-fpie", "-pie",
- "-Wl,--section-start=.text=0x33300000"},
+ CFlags: []string{"-fsanitize-coverage=trace-pc", "-g", "-fpie"},
+ LDFlags: []string{"-pie", "-Wl,--section-start=.text=0x33300000"},
Supports: func(target *targets.Target) bool {
return target.OS == targets.Fuchsia ||
// Fails with "relocation truncated to fit: R_AARCH64_CALL26 against symbol `memcpy'".
@@ -86,8 +87,8 @@ func TestReportGenerator(t *testing.T) {
// This produces a binary that resembles CONFIG_RANDOMIZE_BASE=y.
// Symbols and .text section has addresses around 0x33300000,
// but debug info has all PC ranges around 0 address.
- CFlags: []string{"-fsanitize-coverage=trace-pc", "-g", "-fpie", "-pie",
- "-Wl,--section-start=.text=0x33300000,--emit-relocs"},
+ CFlags: []string{"-fsanitize-coverage=trace-pc", "-g", "-fpie"},
+ LDFlags: []string{"-pie", "-Wl,--section-start=.text=0x33300000,--emit-relocs"},
Supports: func(target *targets.Target) bool {
return target.OS == targets.Fuchsia ||
target.OS == targets.Linux && target.Arch != targets.ARM64 &&
@@ -188,8 +189,9 @@ func buildTestBinary(t *testing.T, target *targets.Target, test Test, dir string
aslrExtraLibs = []string{"-ldl"}
}
- kcovFlags := append([]string{"-c", "-w", "-x", "c", "-o", kcovObj, kcovSrc, aslrDefine}, target.CFlags...)
+ kcovFlags := append([]string{"-c", "-fpie", "-w", "-x", "c", "-o", kcovObj, kcovSrc, aslrDefine}, target.CFlags...)
src := filepath.Join(dir, "main.c")
+ obj := filepath.Join(dir, "main.o")
bin := filepath.Join(dir, target.KernelObject)
if err := osutil.WriteFile(src, []byte(`int main() {}`)); err != nil {
t.Fatal(err)
@@ -198,9 +200,13 @@ func buildTestBinary(t *testing.T, target *targets.Target, test Test, dir string
t.Fatal(err)
}
- linkOrder := append([]string{src, kcovObj}, aslrExtraLibs...)
- flags := append(append(append([]string{"-w", "-o", bin}, linkOrder...), target.CFlags...), test.CFlags...)
- if _, err := osutil.RunCmd(time.Hour, "", target.CCompiler, flags...); err != nil {
+ // We used to compile and link with a single compiler invocation,
+ // but clang has a bug that it tries to link in ubsan runtime when
+ // -fsanitize-coverage=trace-pc is provided during linking and
+ // ubsan runtime is missing for arm/arm64/riscv arches in the llvm packages.
+ // So we first compile with -fsanitize-coverage and then link w/o it.
+ cflags := append(append([]string{"-w", "-c", "-o", obj, src}, target.CFlags...), test.CFlags...)
+ if _, err := osutil.RunCmd(time.Hour, "", target.CCompiler, cflags...); err != nil {
errText := err.Error()
errText = strings.ReplaceAll(errText, "‘", "'")
errText = strings.ReplaceAll(errText, "’", "'")
@@ -210,6 +216,35 @@ func buildTestBinary(t *testing.T, target *targets.Target, test Test, dir string
}
t.Fatal(err)
}
+
+ ldflags := append(append(append([]string{"-o", bin, obj, kcovObj}, aslrExtraLibs...),
+ target.CFlags...), test.LDFlags...)
+ staticIdx, pieIdx := -1, -1
+ for i, arg := range ldflags {
+ switch arg {
+ case "-static":
+ staticIdx = i
+ case "-pie":
+ pieIdx = i
+ }
+ }
+ if target.OS == targets.Fuchsia && pieIdx != -1 {
+ // Fuchsia toolchain fails when given -pie:
+ // clang-12: error: argument unused during compilation: '-pie'
+ ldflags[pieIdx] = ldflags[len(ldflags)-1]
+ ldflags = ldflags[:len(ldflags)-1]
+ } else if pieIdx != -1 && staticIdx != -1 {
+ // -static and -pie are incompatible during linking.
+ ldflags[staticIdx] = ldflags[len(ldflags)-1]
+ ldflags = ldflags[:len(ldflags)-1]
+ }
+ if _, err := osutil.RunCmd(time.Hour, "", target.CCompiler, ldflags...); err != nil {
+ // Arm linker in the big-env image has a bug when linking a clang-produced files.
+ if regexp.MustCompile(`arm-linux-gnueabi.* assertion fail`).MatchString(err.Error()) {
+ t.Skipf("skipping test, broken arm linker (%v)", err)
+ }
+ t.Fatal(err)
+ }
return bin
}