Skip to content

Commit f1bbc66

Browse files
ianlancetaylorgopherbot
authored andcommitted
cmd/link: test that moduledata is in its own section
This is a test for CL 720660. For #76038 Change-Id: I2f630b738ddb5a9c48e3c5d4374c1e995910541a Reviewed-on: https://go-review.googlesource.com/c/go/+/721480 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> Reviewed-by: David Chase <drchase@google.com>
1 parent 003f524 commit f1bbc66

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

src/cmd/link/link_test.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,3 +2114,100 @@ func TestFuncdataPlacement(t *testing.T) {
21142114
t.Errorf("findfunctab address %#x not between %#x and %#x", moddata.findfunctab, pclntabAddr, pclntabEnd)
21152115
}
21162116
}
2117+
2118+
// Test that moduledata winds up in its own .go.module section.
2119+
func TestModuledataPlacement(t *testing.T) {
2120+
testenv.MustHaveGoBuild(t)
2121+
t.Parallel()
2122+
2123+
tmpdir := t.TempDir()
2124+
src := filepath.Join(tmpdir, "x.go")
2125+
if err := os.WriteFile(src, []byte(trivialSrc), 0o444); err != nil {
2126+
t.Fatal(err)
2127+
}
2128+
2129+
exe := filepath.Join(tmpdir, "x.exe")
2130+
cmd := goCmd(t, "build", "-o", exe, src)
2131+
if out, err := cmd.CombinedOutput(); err != nil {
2132+
t.Fatalf("build failed; %v, output:\n%s", err, out)
2133+
}
2134+
2135+
ef, _ := elf.Open(exe)
2136+
mf, _ := macho.Open(exe)
2137+
pf, _ := pe.Open(exe)
2138+
xf, _ := xcoff.Open(exe)
2139+
// TODO: plan9
2140+
if ef == nil && mf == nil && pf == nil && xf == nil {
2141+
t.Skip("unrecognized executable file format")
2142+
}
2143+
2144+
const moddataSymName = "runtime.firstmoduledata"
2145+
switch {
2146+
case ef != nil:
2147+
defer ef.Close()
2148+
2149+
syms, err := ef.Symbols()
2150+
if err != nil {
2151+
t.Fatal(err)
2152+
}
2153+
for _, sym := range syms {
2154+
if sym.Name == moddataSymName {
2155+
sec := ef.Sections[sym.Section]
2156+
if sec.Name != ".go.module" {
2157+
t.Errorf("moduledata in section %s, not .go.module", sec.Name)
2158+
}
2159+
if sym.Value != sec.Addr {
2160+
t.Errorf("moduledata address %#x != section start address %#x", sym.Value, sec.Addr)
2161+
}
2162+
break
2163+
}
2164+
}
2165+
2166+
case mf != nil:
2167+
defer mf.Close()
2168+
2169+
for _, sym := range mf.Symtab.Syms {
2170+
if sym.Name == moddataSymName {
2171+
if sym.Sect == 0 {
2172+
t.Error("moduledata not in a section")
2173+
} else {
2174+
sec := mf.Sections[sym.Sect-1]
2175+
if sec.Name != "__go_module" {
2176+
t.Errorf("moduledata in section %s, not __go.module", sec.Name)
2177+
}
2178+
if sym.Value != sec.Addr {
2179+
t.Errorf("moduledata address %#x != section start address %#x", sym.Value, sec.Addr)
2180+
}
2181+
}
2182+
break
2183+
}
2184+
}
2185+
2186+
case pf != nil:
2187+
defer pf.Close()
2188+
2189+
// On Windows all the Go specific sections seem to
2190+
// get stuffed into a few Windows sections,
2191+
// so there is nothing to test here.
2192+
2193+
case xf != nil:
2194+
defer xf.Close()
2195+
2196+
for _, sym := range xf.Symbols {
2197+
if sym.Name == moddataSymName {
2198+
if sym.SectionNumber == 0 {
2199+
t.Errorf("moduledata not in a section")
2200+
} else {
2201+
sec := xf.Sections[sym.SectionNumber-1]
2202+
if sec.Name != ".go.module" {
2203+
t.Errorf("moduledata in section %s, not .go.module", sec.Name)
2204+
}
2205+
if sym.Value != sec.VirtualAddress {
2206+
t.Errorf("moduledata address %#x != section start address %#x", sym.Value, sec.VirtualAddress)
2207+
}
2208+
}
2209+
break
2210+
}
2211+
}
2212+
}
2213+
}

0 commit comments

Comments
 (0)