1#[cfg(doc)]
4use super::BlockHeader;
5
6#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
12pub struct SymKind(pub u16);
13
14macro_rules! sym_kinds {
15 (
16 $( $code:expr, $name:ident; )*
17 ) => {
18 #[allow(missing_docs)]
19 impl SymKind {
20 $(
21 pub const $name: SymKind = SymKind($code);
22 )*
23 }
24
25 static SYM_NAMES: &[(SymKind, &str)] = &[
26 $(
27 (SymKind($code), stringify!($name)),
28 )*
29 ];
30 }
31}
32
33sym_kinds! {
34 0x0001, S_COMPILE;
35 0x0006, S_END;
36 0x0007, S_SKIP;
37 0x0008, S_CVRESERVE;
38 0x0009, S_OBJNAME_ST;
39 0x000d, S_RETURN;
40 0x0400, S_PROCREF_ST;
42 0x0401, S_DATAREF_ST;
43 0x0402, S_ALIGN;
44 0x0403, S_LPROCREF_ST;
45 0x0404, S_OEM;
46
47 0x1000, S_TI16_MAX;
48 0x1001, S_REGISTER_ST;
49 0x1002, S_CONSTANT_ST;
50 0x1003, S_UDT_ST;
51 0x1004, S_COBOLUDT_ST;
52 0x1005, S_MANYREG_ST;
53 0x1006, S_BPREL32_ST;
54 0x1007, S_LDATA32_ST;
55 0x1008, S_GDATA32_ST;
56 0x1009, S_PUB32_ST;
57 0x100a, S_LPROC32_ST;
58 0x100b, S_GPROC32_ST;
59 0x100c, S_VFTABLE32;
60 0x100d, S_REGREL32_ST;
61 0x100e, S_LTHREAD32_ST;
62 0x100f, S_GTHREAD32_ST;
63 0x1012, S_FRAMEPROC;
64 0x1019, S_ANNOTATION;
65
66 0x1101, S_OBJNAME;
67 0x1102, S_THUNK32;
68 0x1103, S_BLOCK32;
69 0x1104, S_WITH32;
70 0x1105, S_LABEL32;
71 0x1106, S_REGISTER;
72 0x1107, S_CONSTANT;
73 0x1108, S_UDT;
74 0x1109, S_COBOLUDT;
75 0x110a, S_MANYREG;
76 0x110b, S_BPREL32;
77 0x110c, S_LDATA32;
78 0x110d, S_GDATA32;
79 0x110e, S_PUB32;
80 0x110f, S_LPROC32;
81
82 0x1110, S_GPROC32;
83 0x1111, S_REGREL32;
84 0x1112, S_LTHREAD32;
85 0x1113, S_GTHREAD32;
86 0x1116, S_COMPILE2;
87 0x1117, S_MANYREG2;
88 0x1118, S_LPROCIA64;
89 0x1119, S_GPROCIA64;
90 0x111a, S_LOCALSLOT;
91 0x111b, S_PARAMSLOT;
92 0x111c, S_LMANDATA;
93 0x111d, S_GMANDATA;
94 0x111e, S_MANFRAMEREL;
95 0x111f, S_MANREGISTER;
96
97 0x1120, S_MANSLOT;
98 0x1121, S_MANMANYREG;
99 0x1122, S_MANREGREL;
100 0x1123, S_MANMANYREG2;
101 0x1124, S_UNAMESPACE;
102 0x1125, S_PROCREF;
103 0x1126, S_DATAREF;
104 0x1127, S_LPROCREF;
105 0x1128, S_ANNOTATIONREF;
106 0x1129, S_TOKENREF;
107 0x112a, S_GMANPROC;
108 0x112b, S_LMANPROC;
109 0x112c, S_TRAMPOLINE;
110 0x112d, S_MANCONSTANT;
111 0x112e, S_ATTR_FRAMEREL;
112 0x112f, S_ATTR_REGISTER;
113
114 0x1130, S_ATTR_REGREL;
115 0x1131, S_ATTR_MANYREG;
116 0x1132, S_SEPCODE;
117 0x1133, S_LOCAL_2005;
118 0x1134, S_DEFRANGE_2005;
119 0x1135, S_DEFRANGE2_2005;
120 0x1136, S_SECTION;
121 0x1137, S_COFFGROUP;
122 0x1138, S_EXPORT;
123 0x1139, S_CALLSITEINFO;
124 0x113a, S_FRAMECOOKIE;
125 0x113b, S_DISCARDED;
126 0x113c, S_COMPILE3;
127 0x113d, S_ENVBLOCK;
128 0x113e, S_LOCAL;
129 0x113f, S_DEFRANGE;
130
131 0x1140, S_DEFRANGE_SUBFIELD;
132 0x1141, S_DEFRANGE_REGISTER;
133 0x1142, S_DEFRANGE_FRAMEPOINTER_REL;
134 0x1143, S_DEFRANGE_SUBFIELD_REGISTER;
135 0x1144, S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE;
136 0x1145, S_DEFRANGE_REGISTER_REL;
137 0x1146, S_LPROC32_ID;
138 0x1147, S_GPROC32_ID;
139 0x1148, S_LPROCMIPS_ID;
140 0x1149, S_GPROCMIPS_ID;
141 0x114a, S_LPROCIA64_ID;
142 0x114b, S_GPROCIA64_ID;
143 0x114c, S_BUILDINFO;
144 0x114d, S_INLINESITE;
145 0x114e, S_INLINESITE_END;
146 0x114f, S_PROC_ID_END;
147
148 0x1150, S_DEFRANGE_HLSL;
149 0x1151, S_GDATA_HLSL;
150 0x1152, S_LDATA_HLSL;
151 0x1153, S_FILESTATIC;
152 0x1154, S_LOCAL_DPC_GROUPSHARED;
153 0x1155, S_LPROC32_DPC;
154 0x1156, S_LPROC32_DPC_ID;
155 0x1157, S_DEFRANGE_DPC_PTR_TAG;
156 0x1158, S_DPC_SYM_TAG_MAP;
157 0x1159, S_ARMSWITCHTABLE;
158 0x115a, S_CALLEES;
159 0x115b, S_CALLERS;
160 0x115c, S_POGODATA;
161 0x115d, S_INLINESITE2;
162 0x115e, S_HEAPALLOCSITE;
163 0x115f, S_MOD_TYPEREF;
164
165 0x1160, S_REF_MINIPDB;
166 0x1161, S_PDBMAP;
167 0x1162, S_GDATA_HLSL32;
168 0x1163, S_LDATA_HLSL32;
169 0x1164, S_GDATA_HLSL32_EX;
170 0x1165, S_LDATA_HLSL32_EX;
171 0x1167, S_FASTLINK;
172 0x1168, S_INLINEES;
173 0x1169, S_HOTPATCHFUNC;
174}
175
176impl std::fmt::Debug for SymKind {
177 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
178 if let Ok(index) = SYM_NAMES.binary_search_by_key(self, |ii| ii.0) {
179 <str as std::fmt::Display>::fmt(SYM_NAMES[index].1, f)
180 } else {
181 let b0 = (self.0 & 0xff) as u8;
182 let b1 = (self.0 >> 8) as u8;
183 fn to_c(b: u8) -> char {
184 if (32..=126).contains(&b) {
185 char::from(b)
186 } else {
187 '_'
188 }
189 }
190
191 write!(f, "S_(??{:04x} {}{})", self.0, to_c(b1), to_c(b0))
192 }
193 }
194}
195
196#[test]
197fn test_sym_kind_debug() {
198 assert_eq!(format!("{:?}", SymKind::S_GPROC32), "S_GPROC32");
199 assert_eq!(format!("{:?}", SymKind(0x31aa)), "S_(??31aa 1_)");
200}
201
202impl SymKind {
203 pub fn starts_scope(self) -> bool {
206 matches!(
207 self,
208 SymKind::S_GPROC32
209 | SymKind::S_LPROC32
210 | SymKind::S_LPROC32_DPC
211 | SymKind::S_LPROC32_DPC_ID
212 | SymKind::S_GPROC32_ID
213 | SymKind::S_BLOCK32
214 | SymKind::S_THUNK32
215 | SymKind::S_INLINESITE
216 | SymKind::S_INLINESITE2
217 | SymKind::S_SEPCODE
218 | SymKind::S_GMANPROC
219 | SymKind::S_LMANPROC
220 )
221 }
222
223 pub fn is_proc(self) -> bool {
225 matches!(
226 self,
227 SymKind::S_GPROC32
228 | SymKind::S_GPROC32_ID
229 | SymKind::S_GPROC32_ST
230 | SymKind::S_LPROC32
231 | SymKind::S_LPROC32_DPC
232 | SymKind::S_LPROC32_DPC_ID
233 | SymKind::S_LPROC32_ID
234 | SymKind::S_LPROC32_ST
235 )
236 }
237
238 pub fn ends_scope(self) -> bool {
245 matches!(
246 self,
247 SymKind::S_END | SymKind::S_PROC_ID_END | SymKind::S_INLINESITE_END
248 )
249 }
250
251 pub fn is_refsym_target(self) -> bool {
254 matches!(
255 self,
256 SymKind::S_GPROC32
257 | SymKind::S_LPROC32
258 | SymKind::S_GMANPROC
259 | SymKind::S_LMANPROC
260 | SymKind::S_GDATA32
261 | SymKind::S_LDATA32
262 | SymKind::S_ANNOTATION
263 )
264 }
265
266 pub fn is_refsym_source(self) -> bool {
269 matches!(
270 self,
271 SymKind::S_LPROCREF
272 | SymKind::S_PROCREF
273 | SymKind::S_ANNOTATIONREF
274 | SymKind::S_TOKENREF
275 | SymKind::S_DATAREF
276 )
277 }
278}