github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/goobj/objfile_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package goobj 6 7 import ( 8 "bufio" 9 "bytes" 10 "fmt" 11 "os" 12 "testing" 13 14 "github.com/go-asm/go/buildcfg" 15 "github.com/go-asm/go/testenv" 16 17 "github.com/go-asm/go/cmd/bio" 18 "github.com/go-asm/go/cmd/objabi" 19 ) 20 21 func dummyWriter(buf *bytes.Buffer) *Writer { 22 wr := &bio.Writer{Writer: bufio.NewWriter(buf)} // hacky: no file, so cannot seek 23 return NewWriter(wr) 24 } 25 26 func TestReadWrite(t *testing.T) { 27 // Test that we get the same data in a write-read roundtrip. 28 29 // Write a symbol, a relocation, and an aux info. 30 var buf bytes.Buffer 31 w := dummyWriter(&buf) 32 33 var s Sym 34 s.SetABI(1) 35 s.SetType(uint8(objabi.STEXT)) 36 s.SetFlag(0x12) 37 s.SetSiz(12345) 38 s.SetAlign(8) 39 s.Write(w) 40 41 var r Reloc 42 r.SetOff(12) 43 r.SetSiz(4) 44 r.SetType(uint16(objabi.R_ADDR)) 45 r.SetAdd(54321) 46 r.SetSym(SymRef{11, 22}) 47 r.Write(w) 48 49 var a Aux 50 a.SetType(AuxFuncInfo) 51 a.SetSym(SymRef{33, 44}) 52 a.Write(w) 53 54 w.wr.Flush() 55 56 // Read them back and check. 57 b := buf.Bytes() 58 var s2 Sym 59 s2.fromBytes(b) 60 if s2.ABI() != 1 || s2.Type() != uint8(objabi.STEXT) || s2.Flag() != 0x12 || s2.Siz() != 12345 || s2.Align() != 8 { 61 t.Errorf("read Sym2 mismatch: got %v %v %v %v %v", s2.ABI(), s2.Type(), s2.Flag(), s2.Siz(), s2.Align()) 62 } 63 64 b = b[SymSize:] 65 var r2 Reloc 66 r2.fromBytes(b) 67 if r2.Off() != 12 || r2.Siz() != 4 || r2.Type() != uint16(objabi.R_ADDR) || r2.Add() != 54321 || r2.Sym() != (SymRef{11, 22}) { 68 t.Errorf("read Reloc2 mismatch: got %v %v %v %v %v", r2.Off(), r2.Siz(), r2.Type(), r2.Add(), r2.Sym()) 69 } 70 71 b = b[RelocSize:] 72 var a2 Aux 73 a2.fromBytes(b) 74 if a2.Type() != AuxFuncInfo || a2.Sym() != (SymRef{33, 44}) { 75 t.Errorf("read Aux2 mismatch: got %v %v", a2.Type(), a2.Sym()) 76 } 77 } 78 79 var issue41621prolog = ` 80 package main 81 var lines = []string{ 82 ` 83 84 var issue41621epilog = ` 85 } 86 func getLines() []string { 87 return lines 88 } 89 func main() { 90 println(getLines()) 91 } 92 ` 93 94 func TestIssue41621LargeNumberOfRelocations(t *testing.T) { 95 if testing.Short() || (buildcfg.GOARCH != "amd64") { 96 t.Skipf("Skipping large number of relocations test in short mode or on %s", buildcfg.GOARCH) 97 } 98 testenv.MustHaveGoBuild(t) 99 100 tmpdir, err := os.MkdirTemp("", "lotsofrelocs") 101 if err != nil { 102 t.Fatalf("can't create temp directory: %v\n", err) 103 } 104 defer os.RemoveAll(tmpdir) 105 106 // Emit testcase. 107 var w bytes.Buffer 108 fmt.Fprintf(&w, issue41621prolog) 109 for i := 0; i < 1048576+13; i++ { 110 fmt.Fprintf(&w, "\t\"%d\",\n", i) 111 } 112 fmt.Fprintf(&w, issue41621epilog) 113 err = os.WriteFile(tmpdir+"/large.go", w.Bytes(), 0666) 114 if err != nil { 115 t.Fatalf("can't write output: %v\n", err) 116 } 117 118 // Emit go.mod 119 w.Reset() 120 fmt.Fprintf(&w, "module issue41621\n\ngo 1.12\n") 121 err = os.WriteFile(tmpdir+"/go.mod", w.Bytes(), 0666) 122 if err != nil { 123 t.Fatalf("can't write output: %v\n", err) 124 } 125 w.Reset() 126 127 // Build. 128 cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "large") 129 cmd.Dir = tmpdir 130 out, err := cmd.CombinedOutput() 131 if err != nil { 132 t.Fatalf("Build failed: %v, output: %s", err, out) 133 } 134 }