forked from mefistotelis/psx_mnd_sym
-
Notifications
You must be signed in to change notification settings - Fork 0
/
type.go
125 lines (114 loc) · 3.23 KB
/
type.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package sym
import (
"fmt"
"strings"
)
// Type specifies the type of a definition.
//
// A type is made up of a 4-bit basic type specifier, and a set of 2-bit type
// modifiers.
//
// Basic type xxxx
// Modifier xx
// Modifier xx
// Modifier xx
// Modifier xx
// Modifier xx
// Modifier xx
//
// Example.
//
// int * f_0064() {}
//
// Interpretation.
//
// int 0100
// function 10
// pointer 01
// 00
// 00
// 00
// 00
//
// 0x64 = 00 00 00 00 01 10 0100
//
// Example.
//
// int (*v_0094)();
//
// Interpretation.
//
// int 0100
// pointer 01
// function 10
// 00
// 00
// 00
// 00
//
// 0x94 = 00 00 00 00 10 01 0100
type Type uint16
// String returns a string representation of the type.
func (t Type) String() string {
tMods := t.Mods()
mods := make([]string, len(tMods))
for i, mod := range tMods {
mods[i] = mod.String()
}
ss := append(mods, t.Base().String())
return strings.Join(ss, " ")
}
//go:generate stringer -linecomment -type Base
// Base is a base type.
type Base uint8
// Base types.
const (
BaseNull Base = 0x0 // NULL
BaseVoid Base = 0x1 // VOID
BaseChar Base = 0x2 // CHAR
BaseShort Base = 0x3 // SHORT
BaseInt Base = 0x4 // INT
BaseLong Base = 0x5 // LONG
BaseFloat Base = 0x6 // FLOAT
BaseDouble Base = 0x7 // DOUBLE
BaseStruct Base = 0x8 // STRUCT
BaseUnion Base = 0x9 // UNION
BaseEnum Base = 0xA // ENUM
// Member of enum.
BaseMOE Base = 0xB // MOE
BaseUChar Base = 0xC // UCHAR
BaseUShort Base = 0xD // USHORT
BaseUInt Base = 0xE // UINT
BaseULong Base = 0xF // ULONG
)
// Base returns the base type of the type.
func (t Type) Base() Base {
return Base(t & 0xF)
}
//go:generate stringer -linecomment -type Mod
// Mod is a type modifier.
type Mod uint8
// Type modifiers.
const (
ModPointer Mod = 0x1 // PTR
ModFunction Mod = 0x2 // FCN
ModArray Mod = 0x3 // ARY
)
// Mods returns the modifiers of the type.
func (t Type) Mods() []Mod {
var mods []Mod
for i := 0; i < 6; i++ {
// 0b0000000000110000
shift := uint16(4 + i*2)
mask := uint16(0x3) << shift
modMask := Mod((uint16(t) & mask) >> shift)
if modMask == 0 {
continue
}
if !(ModPointer <= modMask && modMask <= ModArray) {
panic(fmt.Sprintf("invalid modifier mask; expected >= 0x1 and <= 0x3, got 0x%X", modMask))
}
mods = append(mods, modMask)
}
return mods
}