aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/ld/elf_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/link/internal/ld/elf_test.go')
-rw-r--r--src/cmd/link/internal/ld/elf_test.go58
1 files changed, 57 insertions, 1 deletions
diff --git a/src/cmd/link/internal/ld/elf_test.go b/src/cmd/link/internal/ld/elf_test.go
index 16bf4039b1..b48cf66038 100644
--- a/src/cmd/link/internal/ld/elf_test.go
+++ b/src/cmd/link/internal/ld/elf_test.go
@@ -198,6 +198,7 @@ func TestElfBindNow(t *testing.T) {
name string
args []string
prog string
+ wantSecsRO []string
mustHaveBuildModePIE bool
mustHaveCGO bool
mustInternalLink bool
@@ -213,6 +214,7 @@ func TestElfBindNow(t *testing.T) {
mustHaveBuildModePIE: true,
mustInternalLink: true,
wantDf1Pie: true,
+ wantSecsRO: []string{".dynamic", ".got"},
},
{
name: "bindnow-linkmode-internal",
@@ -232,6 +234,7 @@ func TestElfBindNow(t *testing.T) {
wantDfBindNow: true,
wantDf1Now: true,
wantDf1Pie: true,
+ wantSecsRO: []string{".dynamic", ".got", ".got.plt"},
},
{
name: "bindnow-pie-linkmode-external",
@@ -242,6 +245,8 @@ func TestElfBindNow(t *testing.T) {
wantDfBindNow: true,
wantDf1Now: true,
wantDf1Pie: true,
+ // NB: external linker produces .plt.got, not .got.plt
+ wantSecsRO: []string{".dynamic", ".got"},
},
}
@@ -251,10 +256,14 @@ func TestElfBindNow(t *testing.T) {
return true
}
}
-
return false
}
+ segContainsSec := func(p *elf.Prog, s *elf.Section) bool {
+ return s.Addr >= p.Vaddr &&
+ s.Addr+s.FileSize <= p.Vaddr+p.Filesz
+ }
+
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.mustInternalLink {
@@ -329,6 +338,53 @@ func TestElfBindNow(t *testing.T) {
if gotDf1Pie := gotDynFlag(flags1, uint64(elf.DF_1_PIE)); gotDf1Pie != test.wantDf1Pie {
t.Fatalf("DT_FLAGS_1 DF_1_PIE got: %v, want: %v", gotDf1Pie, test.wantDf1Pie)
}
+
+ for _, wsroname := range test.wantSecsRO {
+ // Locate section of interest.
+ var wsro *elf.Section
+ for _, s := range elfFile.Sections {
+ if s.Name == wsroname {
+ wsro = s
+ break
+ }
+ }
+ if wsro == nil {
+ t.Fatalf("test %s: can't locate %q section",
+ test.name, wsroname)
+ }
+
+ // Now walk the program headers. Section should be part of
+ // some segment that is readonly.
+ foundRO := false
+ foundSegs := []*elf.Prog{}
+ for _, p := range elfFile.Progs {
+ if segContainsSec(p, wsro) {
+ foundSegs = append(foundSegs, p)
+ if p.Flags == elf.PF_R {
+ foundRO = true
+ }
+ }
+ }
+ if !foundRO {
+ // Things went off the rails. Write out some
+ // useful information for a human looking at the
+ // test failure.
+ t.Logf("test %s: %q section not in readonly segment",
+ wsro.Name, test.name)
+ t.Logf("section %s location: st=0x%x en=0x%x\n",
+ wsro.Name, wsro.Addr, wsro.Addr+wsro.FileSize)
+ t.Logf("sec %s found in these segments: ", wsro.Name)
+ for _, p := range foundSegs {
+ t.Logf(" %q", p.Type)
+ }
+ t.Logf("\nall segments: \n")
+ for k, p := range elfFile.Progs {
+ t.Logf("%d t=%s fl=%s st=0x%x en=0x%x\n",
+ k, p.Type, p.Flags, p.Vaddr, p.Vaddr+p.Filesz)
+ }
+ t.Fatalf("test %s failed", test.name)
+ }
+ }
})
}
}