1 /// Copyright: Copyright (c) 2017-2020 Andrey Penechko.
2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
3 /// Authors: Andrey Penechko.
4 
5 /// Parts that are ported from LLVM: llvm/DebugInfo/CodeView/CodeView.h.
6 
7 /// CV constants
8 ///
9 module vox.be.debug_info.pdb.codeview;
10 
11 import vox.be.debug_info.pdb : StreamReader;
12 
13 // enum CV_CPU_TYPE_e
14 // https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/cv-cpu-type-e
15 enum CV_CPUType : ushort {
16 	Intel8080 = 0x0,
17 	Intel8086 = 0x1,
18 	Intel80286 = 0x2,
19 	Intel80386 = 0x3,
20 	Intel80486 = 0x4,
21 	Pentium = 0x5,
22 	PentiumPro = 0x6,
23 	Pentium3 = 0x7,
24 	MIPS = 0x10,
25 	MIPS16 = 0x11,
26 	MIPS32 = 0x12,
27 	MIPS64 = 0x13,
28 	MIPSI = 0x14,
29 	MIPSII = 0x15,
30 	MIPSIII = 0x16,
31 	MIPSIV = 0x17,
32 	MIPSV = 0x18,
33 	M68000 = 0x20,
34 	M68010 = 0x21,
35 	M68020 = 0x22,
36 	M68030 = 0x23,
37 	M68040 = 0x24,
38 	Alpha = 0x30,
39 	Alpha21164 = 0x31,
40 	Alpha21164A = 0x32,
41 	Alpha21264 = 0x33,
42 	Alpha21364 = 0x34,
43 	PPC601 = 0x40,
44 	PPC603 = 0x41,
45 	PPC604 = 0x42,
46 	PPC620 = 0x43,
47 	PPCFP = 0x44,
48 	PPCBE = 0x45,
49 	SH3 = 0x50,
50 	SH3E = 0x51,
51 	SH3DSP = 0x52,
52 	SH4 = 0x53,
53 	SHMedia = 0x54,
54 	ARM3 = 0x60,
55 	ARM4 = 0x61,
56 	ARM4T = 0x62,
57 	ARM5 = 0x63,
58 	ARM5T = 0x64,
59 	ARM6 = 0x65,
60 	ARM_XMAC = 0x66,
61 	ARM_WMMX = 0x67,
62 	ARM7 = 0x68,
63 	ARM64 = 0x69,
64 	Omni = 0x70,
65 	Ia64 = 0x80,
66 	Ia64_2 = 0x81,
67 	CEE = 0x90,
68 	AM33 = 0xa0,
69 	M32R = 0xb0,
70 	TriCore = 0xc0,
71 	X64 = 0xd0,
72 	EBC = 0xe0,
73 	Thumb = 0xf0,
74 	ARMNT = 0xf4,
75 	D3D11_Shader = 0x100,
76 }
77 
78 /// enum CV_CFL_LANG
79 /// https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/cv-cfl-lang
80 enum CV_SourceLanguage : ubyte {
81   C = 0x00,
82   Cpp = 0x01,
83   Fortran = 0x02,
84   Masm = 0x03,
85   Pascal = 0x04,
86   Basic = 0x05,
87   Cobol = 0x06,
88   Link = 0x07,
89   Cvtres = 0x08,
90   Cvtpgd = 0x09,
91   CSharp = 0x0a,
92   VB = 0x0b,
93   ILAsm = 0x0c,
94   Java = 0x0d,
95   JScript = 0x0e,
96   MSIL = 0x0f,
97   HLSL = 0x10,
98   D = 'D',
99 };
100 
101 
102 enum CV_CallConv : ubyte {
103 	NEAR_C      = 0x00, // near right to left push, caller pops stack
104 	FAR_C       = 0x01, // far right to left push, caller pops stack
105 	NEAR_PASCAL = 0x02, // near left to right push, callee pops stack
106 	FAR_PASCAL  = 0x03, // far left to right push, callee pops stack
107 	NEAR_FAST   = 0x04, // near left to right push with regs, callee pops stack
108 	FAR_FAST    = 0x05, // far left to right push with regs, callee pops stack
109 	SKIPPED     = 0x06, // skipped (unused) call index
110 	NEAR_STD    = 0x07, // near standard call
111 	FAR_STD     = 0x08, // far standard call
112 	NEAR_SYS    = 0x09, // near sys call
113 	FAR_SYS     = 0x0a, // far sys call
114 	THISCALL    = 0x0b, // this call (this passed in register)
115 	MIPSCALL    = 0x0c, // Mips call
116 	GENERIC     = 0x0d, // Generic call sequence
117 	ALPHACALL   = 0x0e, // Alpha call
118 	PPCCALL     = 0x0f, // PPC call
119 	SHCALL      = 0x10, // Hitachi SuperH call
120 	ARMCALL     = 0x11, // ARM call
121 	AM33CALL    = 0x12, // AM33 call
122 	TRICALL     = 0x13, // TriCore Call
123 	SH5CALL     = 0x14, // Hitachi SuperH-5 call
124 	M32RCALL    = 0x15, // M32R Call
125 	CLRCALL     = 0x16, // clr call
126 	INLINE      = 0x17, // Marker for routines always inlined and thus lacking a convention
127 	NEAR_VECTOR = 0x18, // near left to right push with regs, callee pops stack
128 	RESERVED    = 0x19  // first unused call enumeration
129 
130 	// Do NOT add any more machine specific conventions.  This is to be used for
131 	// calling conventions in the source only (e.g. __cdecl, __stdcall).
132 }
133 
134 // enum TRAMP_e
135 // Trampoline subtype
136 enum TrampolineType : ushort {
137 	TrampIncremental, // incremental thunks
138 	BranchIsland // Branch island thunks
139 }
140 
141 // enum THUNK_ORDINAL
142 enum ThunkOrdinal : ubyte {
143 	standard,
144 	thisAdjustor,
145 	virtualCall,
146 	pcode,
147 	jumpDestLoad,
148 	// trampoline thunk ordinals - only for use in Trampoline thunk symbols
149 	trampIncremental,
150 	branchIsland,
151 };
152 
153 // enum CV_HREG_e
154 // llvm: CodeViewRegisters.def
155 enum RegisterId : ushort {
156 	ERR = 30000,
157 	TEB = 30001,
158 	TIMER = 30002,
159 	EFAD1 = 30003,
160 	EFAD2 = 30004,
161 	EFAD3 = 30005,
162 	VFRAME = 30006,
163 	HANDLE = 30007,
164 	PARAMS = 30008,
165 	LOCALS = 30009,
166 	TID = 30010,
167 	ENV = 30011,
168 	CMDLN = 30012,
169 
170 	NONE = 0,
171 	AL = 1,
172 	CL = 2,
173 	DL = 3,
174 	BL = 4,
175 	AH = 5,
176 	CH = 6,
177 	DH = 7,
178 	BH = 8,
179 	AX = 9,
180 	CX = 10,
181 	DX = 11,
182 	BX = 12,
183 	SP = 13,
184 	BP = 14,
185 	SI = 15,
186 	DI = 16,
187 	EAX = 17,
188 	ECX = 18,
189 	EDX = 19,
190 	EBX = 20,
191 	ESP = 21,
192 	EBP = 22,
193 	ESI = 23,
194 	EDI = 24,
195 	ES = 25,
196 	CS = 26,
197 	SS = 27,
198 	DS = 28,
199 	FS = 29,
200 	GS = 30,
201 	IP = 31,
202 	FLAGS = 32,
203 	EIP = 33,
204 	EFLAGS = 34,
205 	TEMP = 40,
206 	TEMPH = 41,
207 	QUOTE = 42,
208 	PCDR3 = 43,
209 	PCDR4 = 44,
210 	PCDR5 = 45,
211 	PCDR6 = 46,
212 	PCDR7 = 47,
213 	CR0 = 80,
214 	CR1 = 81,
215 	CR2 = 82,
216 	CR3 = 83,
217 	CR4 = 84,
218 	DR0 = 90,
219 	DR1 = 91,
220 	DR2 = 92,
221 	DR3 = 93,
222 	DR4 = 94,
223 	DR5 = 95,
224 	DR6 = 96,
225 	DR7 = 97,
226 	GDTR = 110,
227 	GDTL = 111,
228 	IDTR = 112,
229 	IDTL = 113,
230 	LDTR = 114,
231 	TR = 115,
232 
233 	PSEUDO1 = 116,
234 	PSEUDO2 = 117,
235 	PSEUDO3 = 118,
236 	PSEUDO4 = 119,
237 	PSEUDO5 = 120,
238 	PSEUDO6 = 121,
239 	PSEUDO7 = 122,
240 	PSEUDO8 = 123,
241 	PSEUDO9 = 124,
242 
243 	ST0 = 128,
244 	ST1 = 129,
245 	ST2 = 130,
246 	ST3 = 131,
247 	ST4 = 132,
248 	ST5 = 133,
249 	ST6 = 134,
250 	ST7 = 135,
251 	CTRL = 136,
252 	STAT = 137,
253 	TAG = 138,
254 	FPIP = 139,
255 	FPCS = 140,
256 	FPDO = 141,
257 	FPDS = 142,
258 	ISEM = 143,
259 	FPEIP = 144,
260 	FPEDO = 145,
261 
262 	MM0 = 146,
263 	MM1 = 147,
264 	MM2 = 148,
265 	MM3 = 149,
266 	MM4 = 150,
267 	MM5 = 151,
268 	MM6 = 152,
269 	MM7 = 153,
270 
271 	XMM0 = 154,
272 	XMM1 = 155,
273 	XMM2 = 156,
274 	XMM3 = 157,
275 	XMM4 = 158,
276 	XMM5 = 159,
277 	XMM6 = 160,
278 	XMM7 = 161,
279 
280 	MXCSR = 211,
281 
282 	EDXEAX = 212,
283 
284 	EMM0L = 220,
285 	EMM1L = 221,
286 	EMM2L = 222,
287 	EMM3L = 223,
288 	EMM4L = 224,
289 	EMM5L = 225,
290 	EMM6L = 226,
291 	EMM7L = 227,
292 
293 	EMM0H = 228,
294 	EMM1H = 229,
295 	EMM2H = 230,
296 	EMM3H = 231,
297 	EMM4H = 232,
298 	EMM5H = 233,
299 	EMM6H = 234,
300 	EMM7H = 235,
301 
302 	MM00 = 236,
303 	MM01 = 237,
304 	MM10 = 238,
305 	MM11 = 239,
306 	MM20 = 240,
307 	MM21 = 241,
308 	MM30 = 242,
309 	MM31 = 243,
310 	MM40 = 244,
311 	MM41 = 245,
312 	MM50 = 246,
313 	MM51 = 247,
314 	MM60 = 248,
315 	MM61 = 249,
316 	MM70 = 250,
317 	MM71 = 251,
318 
319 	BND0 = 396,
320 	BND1 = 397,
321 	BND2 = 398,
322 
323 
324 	XMM8 = 252,
325 	XMM9 = 253,
326 	XMM10 = 254,
327 	XMM11 = 255,
328 	XMM12 = 256,
329 	XMM13 = 257,
330 	XMM14 = 258,
331 	XMM15 = 259,
332 
333 
334 	SIL = 324,
335 	DIL = 325,
336 	BPL = 326,
337 	SPL = 327,
338 
339 	RAX = 328,
340 	RBX = 329,
341 	RCX = 330,
342 	RDX = 331,
343 	RSI = 332,
344 	RDI = 333,
345 	RBP = 334,
346 	RSP = 335,
347 
348 	R8 = 336,
349 	R9 = 337,
350 	R10 = 338,
351 	R11 = 339,
352 	R12 = 340,
353 	R13 = 341,
354 	R14 = 342,
355 	R15 = 343,
356 
357 	R8B = 344,
358 	R9B = 345,
359 	R10B = 346,
360 	R11B = 347,
361 	R12B = 348,
362 	R13B = 349,
363 	R14B = 350,
364 	R15B = 351,
365 
366 	R8W = 352,
367 	R9W = 353,
368 	R10W = 354,
369 	R11W = 355,
370 	R12W = 356,
371 	R13W = 357,
372 	R14W = 358,
373 	R15W = 359,
374 
375 	R8D = 360,
376 	R9D = 361,
377 	R10D = 362,
378 	R11D = 363,
379 	R12D = 364,
380 	R13D = 365,
381 	R14D = 366,
382 	R15D = 367,
383 
384 	// cvconst.h defines both CV_REG_YMM0 (252) and CV_AMD64_YMM0 (368). Keep the
385 	// original prefix to distinguish them.
386 	AMD64_YMM0 = 368,
387 	AMD64_YMM1 = 369,
388 	AMD64_YMM2 = 370,
389 	AMD64_YMM3 = 371,
390 	AMD64_YMM4 = 372,
391 	AMD64_YMM5 = 373,
392 	AMD64_YMM6 = 374,
393 	AMD64_YMM7 = 375,
394 	AMD64_YMM8 = 376,
395 	AMD64_YMM9 = 377,
396 	AMD64_YMM10 = 378,
397 	AMD64_YMM11 = 379,
398 	AMD64_YMM12 = 380,
399 	AMD64_YMM13 = 381,
400 	AMD64_YMM14 = 382,
401 	AMD64_YMM15 = 383,
402 }
403 
404 
405 enum CV_TYPE : ushort {
406 /*
407 TYPE_RECORD(LF_POINTER, 0x1002, Pointer)
408 TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier)
409 TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure)
410 TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction)
411 TYPE_RECORD(LF_LABEL, 0x000e, Label)
412 TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList)
413 
414 TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList)
415 
416 TYPE_RECORD(LF_ARRAY, 0x1503, Array)
417 TYPE_RECORD(LF_CLASS, 0x1504, Class)
418 TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, Struct, Class)
419 TYPE_RECORD_ALIAS(LF_INTERFACE, 0x1519, Interface, Class)
420 TYPE_RECORD(LF_UNION, 0x1506, Union)
421 TYPE_RECORD(LF_ENUM, 0x1507, Enum)
422 TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2)
423 TYPE_RECORD(LF_VFTABLE, 0x151d, VFTable)
424 TYPE_RECORD(LF_VTSHAPE, 0x000a, VFTableShape)
425 
426 TYPE_RECORD(LF_BITFIELD, 0x1205, BitField)
427 
428 // Member type records. These are generally not length prefixed, and appear
429 // inside of a field list record.
430 MEMBER_RECORD(LF_BCLASS, 0x1400, BaseClass)
431 MEMBER_RECORD_ALIAS(LF_BINTERFACE, 0x151a, BaseInterface, BaseClass)
432 
433 MEMBER_RECORD(LF_VBCLASS, 0x1401, VirtualBaseClass)
434 MEMBER_RECORD_ALIAS(LF_IVBCLASS, 0x1402, IndirectVirtualBaseClass,
435 					VirtualBaseClass)
436 
437 MEMBER_RECORD(LF_VFUNCTAB, 0x1409, VFPtr)
438 MEMBER_RECORD(LF_STMEMBER, 0x150e, StaticDataMember)
439 MEMBER_RECORD(LF_METHOD, 0x150f, OverloadedMethod)
440 MEMBER_RECORD(LF_MEMBER, 0x150d, DataMember)
441 MEMBER_RECORD(LF_NESTTYPE, 0x1510, NestedType)
442 MEMBER_RECORD(LF_ONEMETHOD, 0x1511, OneMethod)
443 MEMBER_RECORD(LF_ENUMERATE, 0x1502, Enumerator)
444 MEMBER_RECORD(LF_INDEX, 0x1404, ListContinuation)
445 
446 // ID leaf records. Subsequent leaf types may be referenced from .debug$S.
447 TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncId)
448 TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFuncId)
449 TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfo)
450 TYPE_RECORD(LF_SUBSTR_LIST, 0x1604, StringList)
451 TYPE_RECORD(LF_STRING_ID, 0x1605, StringId)
452 TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLine)
453 TYPE_RECORD(LF_UDT_MOD_SRC_LINE, 0x1607, UdtModSourceLine)
454 
455 
456 TYPE_RECORD(LF_METHODLIST, 0x1206, MethodOverloadList)
457 */
458 	// 16 bit type records.
459 	LF_MODIFIER_16t = 0x0001,
460 	LF_POINTER_16t = 0x0002,
461 	LF_ARRAY_16t = 0x0003,
462 	LF_CLASS_16t = 0x0004,
463 	LF_STRUCTURE_16t = 0x0005,
464 	LF_UNION_16t = 0x0006,
465 	LF_ENUM_16t = 0x0007,
466 	LF_PROCEDURE_16t = 0x0008,
467 	LF_MFUNCTION_16t = 0x0009,
468 	LF_COBOL0_16t = 0x000b,
469 	LF_COBOL1 = 0x000c,
470 	LF_BARRAY_16t = 0x000d,
471 	LF_NULLLEAF = 0x000f, // LF_NUL
472 	LF_NOTTRAN = 0x0010,
473 	LF_DIMARRAY_16t = 0x0011,
474 	LF_VFTPATH_16t = 0x0012,
475 	LF_PRECOMP_16t = 0x0013,
476 	LF_ENDPRECOMP = 0x0014,
477 	LF_OEM_16t = 0x0015,
478 	LF_TYPESERVER_ST = 0x0016,
479 
480 	LF_SKIP_16t = 0x0200,
481 	LF_ARGLIST_16t = 0x0201,
482 	LF_DEFARG_16t = 0x0202,
483 	LF_LIST = 0x0203,
484 	LF_FIELDLIST_16t = 0x0204,
485 	LF_DERIVED_16t = 0x0205,
486 	LF_BITFIELD_16t = 0x0206,
487 	LF_METHODLIST_16t = 0x0207,
488 	LF_DIMCONU_16t = 0x0208,
489 	LF_DIMCONLU_16t = 0x0209,
490 	LF_DIMVARU_16t = 0x020a,
491 	LF_DIMVARLU_16t = 0x020b,
492 	LF_REFSYM = 0x020c,
493 
494 	// 16 bit member types. Generally not length prefixed.
495 	LF_BCLASS_16t = 0x0400,
496 	LF_VBCLASS_16t = 0x0401,
497 	LF_IVBCLASS_16t = 0x0402,
498 	LF_ENUMERATE_ST = 0x0403,
499 	LF_FRIENDFCN_16t = 0x0404,
500 	LF_INDEX_16t = 0x0405,
501 	LF_MEMBER_16t = 0x0406,
502 	LF_STMEMBER_16t = 0x0407,
503 	LF_METHOD_16t = 0x0408,
504 	LF_NESTTYPE_16t = 0x0409,
505 	LF_VFUNCTAB_16t = 0x040a,
506 	LF_FRIENDCLS_16t = 0x040b,
507 	LF_ONEMETHOD_16t = 0x040c,
508 	LF_VFUNCOFF_16t = 0x040d,
509 
510 	LF_TI16_MAX = 0x1000,
511 
512 	LF_ARRAY_ST = 0x1003,
513 	LF_CLASS_ST = 0x1004,
514 	LF_STRUCTURE_ST = 0x1005,
515 	LF_UNION_ST = 0x1006,
516 	LF_ENUM_ST = 0x1007,
517 	LF_COBOL0 = 0x100a,
518 	LF_BARRAY = 0x100b,
519 	LF_DIMARRAY_ST = 0x100c,
520 	LF_VFTPATH = 0x100d,
521 	LF_PRECOMP_ST = 0x100e,
522 	LF_OEM = 0x100f,
523 	LF_ALIAS_ST = 0x1010,
524 	LF_OEM2 = 0x1011,
525 
526 	LF_SKIP = 0x1200,
527 	LF_DEFARG_ST = 0x1202,
528 	LF_DERIVED = 0x1204,
529 	LF_DIMCONU = 0x1207,
530 	LF_DIMCONLU = 0x1208,
531 	LF_DIMVARU = 0x1209,
532 	LF_DIMVARLU = 0x120a,
533 
534 	// Member type records. These are generally not length prefixed, and appear
535 	// inside of a field list record.
536 	LF_FRIENDFCN_ST = 0x1403,
537 	LF_MEMBER_ST = 0x1405,
538 	LF_STMEMBER_ST = 0x1406,
539 	LF_METHOD_ST = 0x1407,
540 	LF_NESTTYPE_ST = 0x1408,
541 	LF_FRIENDCLS = 0x140a,
542 	LF_ONEMETHOD_ST = 0x140b,
543 	LF_VFUNCOFF = 0x140c,
544 	LF_NESTTYPEEX_ST = 0x140d,
545 	LF_MEMBERMODIFY_ST = 0x140e,
546 	LF_MANAGED_ST = 0x140f,
547 
548 	LF_ST_MAX = 0x1500,
549 	LF_TYPESERVER = 0x1501,
550 	LF_DIMARRAY = 0x1508,
551 	LF_PRECOMP = 0x1509,
552 	LF_ALIAS = 0x150a,
553 	LF_DEFARG = 0x150b,
554 	LF_FRIENDFCN = 0x150c,
555 	LF_NESTTYPEEX = 0x1512,
556 	LF_MEMBERMODIFY = 0x1513,
557 	LF_MANAGED = 0x1514,
558 	LF_STRIDED_ARRAY = 0x1516,
559 	LF_HLSL = 0x1517,
560 	LF_MODIFIER_EX = 0x1518,
561 	LF_VECTOR = 0x151b,
562 	LF_MATRIX = 0x151c,
563 
564 	// ID leaf records. Subsequent leaf types may be referenced from .debug$S.
565 
566 	// Numeric leaf types. These are generally contained in other records, and not
567 	// encountered in the main type stream.
568 	LF_NUMERIC = 0x8000,
569 	LF_CHAR = 0x8000,
570 	LF_SHORT = 0x8001,
571 	LF_USHORT = 0x8002,
572 	LF_LONG = 0x8003,
573 	LF_ULONG = 0x8004,
574 	LF_REAL32 = 0x8005,
575 	LF_REAL64 = 0x8006,
576 	LF_REAL80 = 0x8007,
577 	LF_REAL128 = 0x8008,
578 	LF_QUADWORD = 0x8009,
579 	LF_UQUADWORD = 0x800a,
580 	LF_REAL48 = 0x800b,
581 	LF_COMPLEX32 = 0x800c,
582 	LF_COMPLEX64 = 0x800d,
583 	LF_COMPLEX80 = 0x800e,
584 	LF_COMPLEX128 = 0x800f,
585 	LF_VARSTRING = 0x8010,
586 	LF_OCTWORD = 0x8017,
587 	LF_UOCTWORD = 0x8018,
588 	LF_DECIMAL = 0x8019,
589 	LF_DATE = 0x801a,
590 	LF_UTF8STRING = 0x801b,
591 	LF_REAL16 = 0x801c,
592 
593 	// Padding bytes. These are emitted into alignment bytes in the type stream.
594 	LF_PAD0 = 0xf0,
595 	LF_PAD1 = 0xf1,
596 	LF_PAD2 = 0xf2,
597 	LF_PAD3 = 0xf3,
598 	LF_PAD4 = 0xf4,
599 	LF_PAD5 = 0xf5,
600 	LF_PAD6 = 0xf6,
601 	LF_PAD7 = 0xf7,
602 	LF_PAD8 = 0xf8,
603 	LF_PAD9 = 0xf9,
604 	LF_PAD10 = 0xfa,
605 	LF_PAD11 = 0xfb,
606 	LF_PAD12 = 0xfc,
607 	LF_PAD13 = 0xfd,
608 	LF_PAD14 = 0xfe,
609 	LF_PAD15 = 0xff,
610 }
611 
612 // enum CV_cookietype_e
613 enum FrameCookieType : ubyte {
614 	copy,
615 	xorStackPointer,
616 	xorFramePointer,
617 	xorR13,
618 };
619 
620 // enum BinaryAnnotationOpcode
621 enum BinaryAnnotationsOpcode : uint
622 {
623 	invalid,              // link time pdb contains PADDINGs
624 	codeOffset,           // param : start offset
625 	changeCodeOffsetBase, // param : nth separated code chunk (main code chunk == 0)
626 	changeCodeOffset,     // param : delta of offset
627 	changeCodeLength,     // param : length of code, default next start
628 	changeFile,           // param : fileId
629 	changeLineOffset,     // param : line offset (signed)
630 	changeLineEndDelta,   // param : how many lines, default 1
631 	changeRangeKind,      // param : either 1 (default, for statement) or 0 (for expression)
632 
633 	changeColumnStart,    // param : start column number, 0 means no column info
634 	changeColumnEndDelta, // param : end column number delta (signed)
635 
636 	// Combo opcodes for smaller encoding size.
637 	changeCodeOffsetAndLineOffset, // param : ((sourceDelta << 4) | CodeDelta)
638 	changeCodeLengthAndCodeOffset, // param : codeLength, codeOffset
639 
640 	changeColumnEnd,      // param : end column number
641 }
642 
643 // CVUncompressData
644 uint cvReadCompressedUint(ref StreamReader stream)
645 {
646 	ubyte data = stream.read!ubyte;
647 
648 	if ((data & 0b1000_0000) == 0x00) {
649 		// 0??? ???? - 1 byte
650 		return data;
651 	}
652 	else if ((data & 0b1100_0000) == 0b1000_0000) {
653 		// 10?? ???? - 2 bytes
654 
655 		if (stream.remainingBytes < 1) return uint.max; // invalid value
656 
657 		uint res = (data & 0b0011_1111) << 8;
658 		res |= stream.read!ubyte;
659 		return res;
660 	}
661 	else if ((data & 0b1110_0000) == 0b1100_0000) {
662 		// 110? ???? - 4 bytes
663 
664 		if (stream.remainingBytes < 3) return uint.max; // invalid value
665 
666 		uint res = (data & 0b0001_1111) << 24;
667 		res |= stream.read!ubyte << 16;
668 		res |= stream.read!ubyte << 8;
669 		res |= stream.read!ubyte;
670 		return res;
671 	}
672 
673 	return uint.max; // invalid value
674 }
675 
676 uint numBinaryAnnotationsOpcodeArgs(BinaryAnnotationsOpcode op) {
677 	return op == BinaryAnnotationsOpcode.changeCodeLengthAndCodeOffset ? 2 : 1;
678 }
679 
680 bool binaryAnnotationsIsIntArg(BinaryAnnotationsOpcode op) {
681 	return op == BinaryAnnotationsOpcode.changeLineOffset ||
682 		op == BinaryAnnotationsOpcode.changeColumnEndDelta;
683 }
684 
685 // encodes negative int as positive int. Uses 0th bit as sign.
686 uint cvEncodeSignedInt32(int input) {
687 	return (input >= 0)
688 		? (( input) << 1) | 0
689 		: ((-input) << 1) | 1;
690 }
691 
692 int cvDecodeSignedInt32(uint input) {
693 	return (input & 1)
694 		? -cast(int)(input >> 1)
695 		:  cast(int)(input >> 1);
696 }