1 | #![allow (non_snake_case)] |
2 | |
3 | use super::Write; |
4 | use super::*; |
5 | use metadata::*; |
6 | |
7 | #[derive (Default)] |
8 | pub struct Tables { |
9 | // TODO: use BTreeSet for tables that have a primary key, unless they are naturally sorted. |
10 | pub Assembly: Vec<Assembly>, |
11 | pub AssemblyRef: Vec<AssemblyRef>, |
12 | pub ClassLayout: Vec<ClassLayout>, |
13 | pub Constant: Vec<Constant>, |
14 | pub CustomAttribute: Vec<CustomAttribute>, |
15 | pub Field: Vec<Field>, |
16 | pub GenericParam: Vec<GenericParam>, |
17 | pub ImplMap: Vec<ImplMap>, |
18 | pub InterfaceImpl: Vec<InterfaceImpl>, |
19 | pub MemberRef: Vec<MemberRef>, |
20 | pub MethodDef: Vec<MethodDef>, |
21 | pub Module: Vec<Module>, |
22 | pub ModuleRef: Vec<ModuleRef>, |
23 | pub NestedClass: Vec<NestedClass>, |
24 | pub Param: Vec<Param>, |
25 | pub Property: Vec<Property>, |
26 | pub TypeDef: Vec<TypeDef>, |
27 | pub TypeRef: Vec<TypeRef>, |
28 | pub TypeSpec: Vec<TypeSpec>, |
29 | } |
30 | |
31 | #[derive (Default)] |
32 | pub struct Assembly { |
33 | pub HashAlgId: u32, |
34 | pub MajorVersion: u16, |
35 | pub MinorVersion: u16, |
36 | pub BuildNumber: u16, |
37 | pub RevisionNumber: u16, |
38 | pub Flags: u32, |
39 | pub PublicKey: u32, |
40 | pub Name: u32, |
41 | pub Culture: u32, |
42 | } |
43 | |
44 | #[derive (Default)] |
45 | pub struct AssemblyRef { |
46 | pub MajorVersion: u16, |
47 | pub MinorVersion: u16, |
48 | pub BuildNumber: u16, |
49 | pub RevisionNumber: u16, |
50 | pub Flags: u32, |
51 | pub PublicKeyOrToken: u32, |
52 | pub Name: u32, |
53 | pub Culture: u32, |
54 | pub HashValue: u32, |
55 | } |
56 | |
57 | #[derive (Default)] |
58 | pub struct ClassLayout { |
59 | pub PackingSize: u16, |
60 | pub ClassSize: u32, |
61 | pub Parent: u32, |
62 | } |
63 | |
64 | #[derive (Default)] |
65 | pub struct Constant { |
66 | pub Type: u16, |
67 | pub Parent: u32, |
68 | pub Value: u32, |
69 | } |
70 | |
71 | #[derive (Default)] |
72 | pub struct CustomAttribute { |
73 | pub Parent: u32, |
74 | pub Type: u32, |
75 | pub Value: u32, |
76 | } |
77 | |
78 | #[derive (Default)] |
79 | pub struct Field { |
80 | pub Flags: u16, |
81 | pub Name: u32, |
82 | pub Signature: u32, |
83 | } |
84 | |
85 | #[derive (Default)] |
86 | pub struct GenericParam { |
87 | pub Number: u16, |
88 | pub Flags: u16, |
89 | pub Owner: u32, |
90 | pub Name: u32, |
91 | } |
92 | |
93 | #[derive (Default)] |
94 | pub struct ImplMap { |
95 | pub MappingFlags: u16, |
96 | pub MemberForwarded: u32, |
97 | pub ImportName: u32, |
98 | pub ImportScope: u32, |
99 | } |
100 | |
101 | #[derive (Default)] |
102 | pub struct InterfaceImpl { |
103 | pub Class: u32, |
104 | pub Interface: u32, |
105 | } |
106 | |
107 | #[derive (Default)] |
108 | pub struct MemberRef { |
109 | pub Class: u32, |
110 | pub Name: u32, |
111 | pub Signature: u32, |
112 | } |
113 | |
114 | #[derive (Default)] |
115 | pub struct MethodDef { |
116 | pub RVA: u32, |
117 | pub ImplFlags: u16, |
118 | pub Flags: u16, |
119 | pub Name: u32, |
120 | pub Signature: u32, |
121 | pub ParamList: u32, |
122 | } |
123 | |
124 | #[derive (Default)] |
125 | pub struct Module { |
126 | pub Generation: u16, |
127 | pub Name: u32, |
128 | pub Mvid: u32, |
129 | pub EncId: u32, |
130 | pub EncBaseId: u32, |
131 | } |
132 | |
133 | #[derive (Default)] |
134 | pub struct ModuleRef { |
135 | pub Name: u32, |
136 | } |
137 | |
138 | #[derive (Default)] |
139 | pub struct NestedClass { |
140 | pub NestedClass: u32, |
141 | pub EnclosingClass: u32, |
142 | } |
143 | |
144 | #[derive (Default)] |
145 | pub struct Param { |
146 | pub Flags: u16, |
147 | pub Sequence: u16, |
148 | pub Name: u32, |
149 | } |
150 | |
151 | #[derive (Default)] |
152 | pub struct Property { |
153 | pub Flags: u16, |
154 | pub Name: u32, |
155 | pub Type: u32, |
156 | } |
157 | |
158 | #[derive (Default)] |
159 | pub struct TypeDef { |
160 | pub Flags: u32, |
161 | pub TypeName: u32, |
162 | pub TypeNamespace: u32, |
163 | pub Extends: u32, |
164 | pub FieldList: u32, |
165 | pub MethodList: u32, |
166 | } |
167 | |
168 | #[derive (Default)] |
169 | pub struct TypeRef { |
170 | pub ResolutionScope: u32, |
171 | pub TypeName: u32, |
172 | pub TypeNamespace: u32, |
173 | } |
174 | |
175 | #[derive (Default)] |
176 | pub struct TypeSpec { |
177 | pub Signature: u32, |
178 | } |
179 | |
180 | impl Tables { |
181 | pub fn into_stream(self) -> Vec<u8> { |
182 | if [self.AssemblyRef.len(), self.ClassLayout.len(), self.Constant.len(), self.CustomAttribute.len(), self.Field.len(), self.GenericParam.len(), self.ImplMap.len(), self.InterfaceImpl.len(), self.MemberRef.len(), self.MethodDef.len(), self.Module.len(), self.ModuleRef.len(), self.NestedClass.len(), self.Param.len(), self.Property.len(), self.TypeDef.len(), self.TypeRef.len(), self.TypeSpec.len()].iter().any(|len| *len > u32::MAX as usize) { |
183 | panic!("metadata table too large" ); |
184 | } |
185 | |
186 | let resolution_scope = coded_index_size(&[self.Module.len(), self.ModuleRef.len(), self.AssemblyRef.len(), self.TypeRef.len()]); |
187 | |
188 | let type_def_or_ref = coded_index_size(&[self.TypeDef.len(), self.TypeRef.len(), self.TypeSpec.len()]); |
189 | |
190 | let has_constant = coded_index_size(&[self.Field.len(), self.Param.len(), self.Property.len()]); |
191 | |
192 | let type_or_method_def = coded_index_size(&[self.TypeDef.len(), self.MethodDef.len()]); |
193 | |
194 | let valid_tables: u64 = 1 << 0 | // Module |
195 | 1 << 0x01 | // TypeRef |
196 | 1 << 0x02 | // TypeDef |
197 | 1 << 0x04 | // Field |
198 | 1 << 0x06 | // MethodDef |
199 | 1 << 0x08 | // Param |
200 | 1 << 0x09 | // InterfaceImpl |
201 | 1 << 0x0A | // MemberRef |
202 | 1 << 0x0B | // Constant |
203 | 1 << 0x0C | // CustomAttribute |
204 | 1 << 0x0F | // ClassLayout |
205 | 1 << 0x17 | // Property |
206 | 1 << 0x1A | // ModuleRef |
207 | 1 << 0x1B | // TypeSpec |
208 | 1 << 0x1C | // ImplMap |
209 | 1 << 0x20 | // Assembly |
210 | 1 << 0x23 | // AssemblyRef |
211 | 1 << 0x29 | // NestedClass |
212 | 1 << 0x2A; // GenericParam |
213 | |
214 | // The table stream header... |
215 | |
216 | let mut buffer = Vec::new(); |
217 | buffer.write_u32(0); // Reserved |
218 | buffer.write_u8(2); // MajorVersion |
219 | buffer.write_u8(0); // MinorVersion |
220 | buffer.write_u8(0b111); // HeapSizes |
221 | buffer.write_u8(0); // Reserved |
222 | buffer.write_u64(valid_tables); |
223 | buffer.write_u64(0); // Sorted |
224 | |
225 | // Followed by the length of each of the valid tables... |
226 | |
227 | buffer.write_u32(self.Module.len() as u32); |
228 | buffer.write_u32(self.TypeRef.len() as u32); |
229 | buffer.write_u32(self.TypeDef.len() as u32); |
230 | buffer.write_u32(self.Field.len() as u32); |
231 | buffer.write_u32(self.MethodDef.len() as u32); |
232 | buffer.write_u32(self.Param.len() as u32); |
233 | buffer.write_u32(self.InterfaceImpl.len() as u32); |
234 | buffer.write_u32(self.MemberRef.len() as u32); |
235 | buffer.write_u32(self.Constant.len() as u32); |
236 | buffer.write_u32(self.CustomAttribute.len() as u32); |
237 | buffer.write_u32(self.ClassLayout.len() as u32); |
238 | buffer.write_u32(self.Property.len() as u32); |
239 | buffer.write_u32(self.ModuleRef.len() as u32); |
240 | buffer.write_u32(self.TypeSpec.len() as u32); |
241 | buffer.write_u32(self.ImplMap.len() as u32); |
242 | buffer.write_u32(self.Assembly.len() as u32); |
243 | buffer.write_u32(self.AssemblyRef.len() as u32); |
244 | buffer.write_u32(self.NestedClass.len() as u32); |
245 | buffer.write_u32(self.GenericParam.len() as u32); |
246 | |
247 | // Followed by each table's rows... |
248 | |
249 | for x in self.Module { |
250 | buffer.write_u16(x.Generation); |
251 | buffer.write_u32(x.Name); |
252 | buffer.write_u32(x.Mvid); |
253 | buffer.write_u32(x.EncId); |
254 | buffer.write_u32(x.EncBaseId); |
255 | } |
256 | |
257 | for x in self.TypeRef { |
258 | buffer.write_code(x.ResolutionScope, resolution_scope); |
259 | buffer.write_u32(x.TypeName); |
260 | buffer.write_u32(x.TypeNamespace); |
261 | } |
262 | |
263 | for x in &self.TypeDef { |
264 | buffer.write_u32(x.Flags); |
265 | buffer.write_u32(x.TypeName); |
266 | buffer.write_u32(x.TypeNamespace); |
267 | buffer.write_code(x.Extends, type_def_or_ref); |
268 | buffer.write_index(x.FieldList, self.Field.len()); |
269 | buffer.write_index(x.MethodList, self.MethodDef.len()); |
270 | } |
271 | |
272 | for x in self.Field { |
273 | buffer.write_u16(x.Flags); |
274 | buffer.write_u32(x.Name); |
275 | buffer.write_u32(x.Signature); |
276 | } |
277 | |
278 | for x in self.MethodDef { |
279 | buffer.write_u32(x.RVA); |
280 | buffer.write_u16(x.ImplFlags); |
281 | buffer.write_u16(x.Flags); |
282 | buffer.write_u32(x.Name); |
283 | buffer.write_u32(x.Signature); |
284 | buffer.write_index(x.ParamList, self.Param.len()); |
285 | } |
286 | |
287 | for x in self.Param { |
288 | buffer.write_u16(x.Flags); |
289 | buffer.write_u16(x.Sequence); |
290 | buffer.write_u32(x.Name); |
291 | } |
292 | |
293 | for x in self.InterfaceImpl { |
294 | buffer.write_index(x.Class, self.TypeDef.len()); |
295 | buffer.write_code(x.Interface, type_def_or_ref); |
296 | } |
297 | |
298 | for x in self.Constant { |
299 | buffer.write_u16(x.Type); |
300 | buffer.write_code(x.Parent, has_constant); |
301 | buffer.write_u32(x.Value); |
302 | } |
303 | |
304 | for x in self.TypeSpec { |
305 | buffer.write_u32(x.Signature); |
306 | } |
307 | |
308 | for x in self.Assembly { |
309 | buffer.write_u32(x.HashAlgId); |
310 | buffer.write_u16(x.MajorVersion); |
311 | buffer.write_u16(x.MinorVersion); |
312 | buffer.write_u16(x.BuildNumber); |
313 | buffer.write_u16(x.RevisionNumber); |
314 | buffer.write_u32(x.Flags); |
315 | buffer.write_u32(x.PublicKey); |
316 | buffer.write_u32(x.Name); |
317 | buffer.write_u32(x.Culture); |
318 | } |
319 | |
320 | for x in self.AssemblyRef { |
321 | buffer.write_u16(x.MajorVersion); |
322 | buffer.write_u16(x.MinorVersion); |
323 | buffer.write_u16(x.BuildNumber); |
324 | buffer.write_u16(x.RevisionNumber); |
325 | buffer.write_u32(x.Flags); |
326 | buffer.write_u32(x.PublicKeyOrToken); |
327 | buffer.write_u32(x.Name); |
328 | buffer.write_u32(x.Culture); |
329 | buffer.write_u32(x.HashValue); |
330 | } |
331 | |
332 | for x in self.GenericParam { |
333 | buffer.write_u16(x.Number); |
334 | buffer.write_u16(x.Flags); |
335 | buffer.write_code(x.Owner, type_or_method_def); |
336 | buffer.write_u32(x.Name); |
337 | } |
338 | |
339 | // TODO: sort GenericParam table prior to writing. This needs to be done for all tables with a primary index. See II.22 |
340 | |
341 | // TODO: do these get naturally sorted by virtue of how they're pushed into "tables" in type def order? |
342 | |
343 | // Table Primary Key Column |
344 | // ClassLayout Parent |
345 | // Constant Parent |
346 | // CustomAttribute Parent |
347 | // DeclSecurity Parent |
348 | // FieldLayout Field |
349 | // FieldMarshal Parent |
350 | // FieldRVA Field |
351 | // GenericParam Owner |
352 | // GenericParamConstraint Owner |
353 | // ImplMap MemberForwarded |
354 | // InterfaceImpl Class |
355 | // MethodImpl Class |
356 | // MethodSemantics Association |
357 | // NestedClass NestedClass |
358 | |
359 | buffer.into_stream() |
360 | } |
361 | } |
362 | |