Skip to content

Commit f5c911a

Browse files
Fix natives for debug/pe
1 parent 91f1d44 commit f5c911a

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//go:build js
2+
// +build js
3+
4+
package pe
5+
6+
import (
7+
"encoding/binary"
8+
"fmt"
9+
"io"
10+
)
11+
12+
// bytesBufferLite is a simplified bytes.Buffer to avoid
13+
// including `bytes` as a new import into the pe package.
14+
type bytesBufferLite struct {
15+
data []byte
16+
off int
17+
}
18+
19+
func (buf *bytesBufferLite) Write(p []byte) (int, error) {
20+
buf.data = append(buf.data, p...)
21+
return len(p), nil
22+
}
23+
24+
func (buf *bytesBufferLite) Read(p []byte) (int, error) {
25+
n := copy(p, buf.data[buf.off:])
26+
buf.off += n
27+
return n, nil
28+
}
29+
30+
func copyToAuxFormat5(sym *COFFSymbol) (*COFFSymbolAuxFormat5, error) {
31+
buf := &bytesBufferLite{data: make([]byte, 0, 20)}
32+
if err := binary.Write(buf, binary.LittleEndian, sym); err != nil {
33+
return nil, err
34+
}
35+
aux := &COFFSymbolAuxFormat5{}
36+
if err := binary.Read(buf, binary.LittleEndian, aux); err != nil {
37+
return nil, err
38+
}
39+
return aux, nil
40+
}
41+
42+
func copyFromAuxFormat5(aux *COFFSymbolAuxFormat5) (*COFFSymbol, error) {
43+
buf := &bytesBufferLite{data: make([]byte, 0, 20)}
44+
if err := binary.Write(buf, binary.LittleEndian, aux); err != nil {
45+
return nil, err
46+
}
47+
sym := &COFFSymbol{}
48+
if err := binary.Read(buf, binary.LittleEndian, sym); err != nil {
49+
return nil, err
50+
}
51+
return sym, nil
52+
}
53+
54+
func readCOFFSymbols(fh *FileHeader, r io.ReadSeeker) ([]COFFSymbol, error) {
55+
if fh.PointerToSymbolTable == 0 {
56+
return nil, nil
57+
}
58+
if fh.NumberOfSymbols <= 0 {
59+
return nil, nil
60+
}
61+
_, err := r.Seek(int64(fh.PointerToSymbolTable), seekStart)
62+
if err != nil {
63+
return nil, fmt.Errorf("fail to seek to symbol table: %v", err)
64+
}
65+
syms := make([]COFFSymbol, fh.NumberOfSymbols)
66+
naux := 0
67+
for k := range syms {
68+
if naux == 0 {
69+
err = binary.Read(r, binary.LittleEndian, &syms[k])
70+
if err != nil {
71+
return nil, fmt.Errorf("fail to read symbol table: %v", err)
72+
}
73+
naux = int(syms[k].NumberOfAuxSymbols)
74+
} else {
75+
naux--
76+
// The following was reading into one struct with the same memory
77+
// footprint as another struck. This doesn't work in JS so the
78+
// `syms` value is left with a bunch of defaults. So replace
79+
// aux := (*COFFSymbolAuxFormat5)(unsafe.Pointer(&syms[k]))
80+
// (an in memory remap) with the following read and then copy.
81+
aux := &COFFSymbolAuxFormat5{}
82+
err = binary.Read(r, binary.LittleEndian, aux)
83+
if err != nil {
84+
return nil, fmt.Errorf("fail to read symbol table: %v", err)
85+
}
86+
pesymn, err := copyFromAuxFormat5(aux)
87+
if err != nil {
88+
return nil, err
89+
}
90+
syms[k] = *pesymn
91+
}
92+
}
93+
if naux != 0 {
94+
return nil, fmt.Errorf("fail to read symbol table: %d aux symbols unread", naux)
95+
}
96+
return syms, nil
97+
}
98+
99+
func (f *File) COFFSymbolReadSectionDefAux(idx int) (*COFFSymbolAuxFormat5, error) {
100+
var rv *COFFSymbolAuxFormat5
101+
if idx < 0 || idx >= len(f.COFFSymbols) {
102+
return rv, fmt.Errorf("invalid symbol index")
103+
}
104+
pesym := &f.COFFSymbols[idx]
105+
const IMAGE_SYM_CLASS_STATIC = 3
106+
if pesym.StorageClass != uint8(IMAGE_SYM_CLASS_STATIC) {
107+
return rv, fmt.Errorf("incorrect symbol storage class")
108+
}
109+
if pesym.NumberOfAuxSymbols == 0 || idx+1 >= len(f.COFFSymbols) {
110+
return rv, fmt.Errorf("aux symbol unavailable")
111+
}
112+
pesymn := &f.COFFSymbols[idx+1]
113+
// The following was reading one struct as another struct with
114+
// the same memory footprint. This doesn't work in JS so the
115+
// `rv` value is left with a bunch of `undefined`s. So replace
116+
// rv = (*COFFSymbolAuxFormat5)(unsafe.Pointer(pesymn))
117+
// (an in memory remap) with the following copy.
118+
return copyToAuxFormat5(pesymn)
119+
}

0 commit comments

Comments
 (0)