| // Copyright 2022 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package pe | |
| import ( | |
| "fmt" | |
| "testing" | |
| ) | |
| type testpoint struct { | |
| name string | |
| ok bool | |
| err string | |
| auxstr string | |
| } | |
| func TestReadCOFFSymbolAuxInfo(t *testing.T) { | |
| testpoints := map[int]testpoint{ | |
| 39: testpoint{ | |
| name: ".rdata$.refptr.__native_startup_lock", | |
| ok: true, | |
| auxstr: "{Size:8 NumRelocs:1 NumLineNumbers:0 Checksum:0 SecNum:16 Selection:2 _:[0 0 0]}", | |
| }, | |
| 81: testpoint{ | |
| name: ".debug_line", | |
| ok: true, | |
| auxstr: "{Size:994 NumRelocs:1 NumLineNumbers:0 Checksum:1624223678 SecNum:32 Selection:0 _:[0 0 0]}", | |
| }, | |
| 155: testpoint{ | |
| name: ".file", | |
| ok: false, | |
| err: "incorrect symbol storage class", | |
| }, | |
| } | |
| // The testdata PE object file below was selected from a release | |
| // build from https://github.com/mstorsjo/llvm-mingw/releases; it | |
| // corresponds to the mingw "crt2.o" object. The object itself was | |
| // built using an x86_64 HOST=linux TARGET=windows clang cross | |
| // compiler based on LLVM 13. More build details can be found at | |
| // https://github.com/mstorsjo/llvm-mingw/releases. | |
| f, err := Open("testdata/llvm-mingw-20211002-msvcrt-x86_64-crt2") | |
| if err != nil { | |
| t.Errorf("open failed with %v", err) | |
| } | |
| defer f.Close() | |
| for k := range f.COFFSymbols { | |
| tp, ok := testpoints[k] | |
| if !ok { | |
| continue | |
| } | |
| sym := &f.COFFSymbols[k] | |
| if sym.NumberOfAuxSymbols == 0 { | |
| t.Errorf("expected aux symbols for sym %d", k) | |
| continue | |
| } | |
| name, nerr := sym.FullName(f.StringTable) | |
| if nerr != nil { | |
| t.Errorf("FullName(%d) failed with %v", k, nerr) | |
| continue | |
| } | |
| if name != tp.name { | |
| t.Errorf("name check for %d, got %s want %s", k, name, tp.name) | |
| continue | |
| } | |
| ap, err := f.COFFSymbolReadSectionDefAux(k) | |
| if tp.ok { | |
| if err != nil { | |
| t.Errorf("unexpected failure on %d, got error %v", k, err) | |
| continue | |
| } | |
| got := fmt.Sprintf("%+v", *ap) | |
| if got != tp.auxstr { | |
| t.Errorf("COFFSymbolReadSectionDefAux on %d bad return, got:\n%s\nwant:\n%s\n", k, got, tp.auxstr) | |
| continue | |
| } | |
| } else { | |
| if err == nil { | |
| t.Errorf("unexpected non-failure on %d", k) | |
| continue | |
| } | |
| got := fmt.Sprintf("%v", err) | |
| if got != tp.err { | |
| t.Errorf("COFFSymbolReadSectionDefAux %d wrong error, got %q want %q", k, got, tp.err) | |
| continue | |
| } | |
| } | |
| } | |
| } |