llvm_bca/
llvm_bca.rs

1#![allow(non_camel_case_types)]
2use llvm_bitcode::BitStreamReader;
3use llvm_bitcode::bitcode::Signature;
4use llvm_bitcode::read::BlockItem;
5use llvm_bitcode::read::BlockIter;
6use llvm_bitcode::read::Error;
7use num_enum::TryFromPrimitive;
8
9fn main() {
10    let path = std::env::args()
11        .nth(1)
12        .expect("Provide file path to a .bc file");
13    let file = std::fs::read(&path).unwrap();
14
15    let mut reader = BitStreamReader::new();
16    let (sig, bitcode) = Signature::parse(&file).unwrap();
17
18    println!(
19        "<BITCODE_WRAPPER_HEADER Magic=0x{:08x} Version=0x{:08x} Offset=0x{:08x} Size=0x{:08x} CPUType=0x{:08x}/>",
20        sig.magic, sig.version, sig.offset, sig.size, sig.cpu_type
21    );
22    iter_block(reader.iter_bitcode(bitcode), 0).unwrap();
23}
24
25fn iter_block(mut block: BlockIter, depth: usize) -> Result<(), Error> {
26    let outer_block_id = block.id;
27    while let Some(b) = block.next()? {
28        match b {
29            BlockItem::Block(b) => {
30                let tag_name = block_tag_name(b.id as _);
31                println!(
32                    "{:indent$}<{tag_name} NumWords={nw} BlockCodeSize={ab}>",
33                    "",
34                    nw = b.debug_data_len().unwrap_or(0) / 4,
35                    ab = b.debug_abbrev_width(),
36                    indent = depth * 2
37                );
38                iter_block(b, depth + 1)?;
39                println!("{:indent$}</{tag_name}>", "", indent = depth * 2);
40            }
41            BlockItem::Record(mut r) => {
42                let tag_name = record_tag_name(outer_block_id as _, r.id as _);
43                print!("{:indent$}<{tag_name}", "", indent = depth * 2);
44                if let Some(a) = r.debug_abbrev_id() {
45                    print!(" abbrevid={a}");
46                }
47                let fields = r
48                    .by_ref()
49                    .map(|f| f.map(|f| f as i64))
50                    .collect::<Result<Vec<_>, _>>()?;
51                for (i, &op) in fields.iter().enumerate() {
52                    print!(" op{i}={op}");
53                }
54                let payload: Result<_, _> = r.payload();
55                match payload {
56                    Ok(Some(llvm_bitcode::bitcode::Payload::Array(a))) => {
57                        for (i, op) in a.iter().enumerate() {
58                            print!(" op{}={op}", i + fields.len());
59                        }
60                        if !a.is_empty() && a.iter().all(|&c| (c as u8) >= 0x20 && (c as u8) < 0x7F)
61                        {
62                            // lol bug in the original
63                            let s: String = a.iter().map(|&c| c as u8 as char).collect();
64                            println!("/> record string = '{s}'");
65                        } else {
66                            println!("/>");
67                        }
68                    }
69                    Ok(Some(llvm_bitcode::bitcode::Payload::Char6String(s))) => {
70                        for (i, op) in s.chars().enumerate() {
71                            print!(" op{}={}", i + fields.len(), op as u32);
72                        }
73                        if s.is_empty() {
74                            println!("/>");
75                        } else {
76                            println!("/> record string = '{s}'");
77                        }
78                    }
79                    Ok(None) => {
80                        if r.debug_abbrev_id().is_some()
81                            && fields.len() > 1
82                            && fields.iter().skip(1).all(|&c| (0x20..0x7F).contains(&c))
83                        {
84                            let s: String =
85                                fields.iter().skip(1).map(|&c| c as u8 as char).collect();
86                            println!("/> record string = '{s}'");
87                        } else {
88                            println!("/>");
89                        }
90                    }
91                    Ok(Some(llvm_bitcode::bitcode::Payload::Blob(b))) => {
92                        if b.len() < 10000 && b.iter().all(|&c| (0x20..0x7F).contains(&c)) {
93                            println!("/> blob data = {}", String::from_utf8_lossy(&b));
94                        } else {
95                            print!("/> blob data = ");
96                            if b.len() > 50 {
97                                print!("unprintable, {} bytes.", b.len());
98                            } else {
99                                print!("'");
100                                for b in b {
101                                    print!("{b:02x}");
102                                }
103                                print!("'");
104                            }
105                            println!();
106                        }
107                    }
108                    Err(err) => print!("/> payload_err={err}"),
109                }
110            }
111        }
112    }
113    Ok(())
114}
115
116fn block_tag_name(id: u32) -> &'static str {
117    use Blocks::*;
118    match Blocks::try_from(id).unwrap() {
119        MODULE_BLOCK_ID => "MODULE_BLOCK",
120        PARAMATTR_BLOCK_ID => "PARAMATTR_BLOCK",
121        PARAMATTR_GROUP_BLOCK_ID => "PARAMATTR_GROUP_BLOCK_ID",
122        CONSTANTS_BLOCK_ID => "CONSTANTS_BLOCK",
123        FUNCTION_BLOCK_ID => "FUNCTION_BLOCK",
124        IDENTIFICATION_BLOCK_ID => "IDENTIFICATION_BLOCK_ID",
125        VALUE_SYMTAB_BLOCK_ID => "VALUE_SYMTAB",
126        METADATA_BLOCK_ID => "METADATA_BLOCK",
127        METADATA_ATTACHMENT_ID => "METADATA_ATTACHMENT_BLOCK",
128        TYPE_BLOCK_ID_NEW => "TYPE_BLOCK_ID",
129        USELIST_BLOCK_ID => "USELIST_BLOCK",
130        MODULE_STRTAB_BLOCK_ID => "MODULE_STRTAB_BLOCK",
131        GLOBALVAL_SUMMARY_BLOCK_ID => "GLOBALVAL_SUMMARY_BLOCK",
132        OPERAND_BUNDLE_TAGS_BLOCK_ID => "OPERAND_BUNDLE_TAGS_BLOCK",
133        METADATA_KIND_BLOCK_ID => "METADATA_KIND_BLOCK",
134        STRTAB_BLOCK_ID => "STRTAB_BLOCK",
135        FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID => "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK",
136        SYMTAB_BLOCK_ID => "SYMTAB_BLOCK",
137        SYNC_SCOPE_NAMES_BLOCK_ID => "UnknownBlock26", //"SYNC_SCOPE_NAMES_BLOCK",
138    }
139}
140
141fn record_tag_name(block: u32, record: u32) -> &'static str {
142    match Blocks::try_from(block).unwrap() {
143        Blocks::MODULE_BLOCK_ID => match ModuleCodes::try_from(record).unwrap() {
144            ModuleCodes::MODULE_CODE_VERSION => "VERSION",
145            ModuleCodes::MODULE_CODE_TRIPLE => "TRIPLE",
146            ModuleCodes::MODULE_CODE_DATALAYOUT => "DATALAYOUT",
147            ModuleCodes::MODULE_CODE_ASM => "ASM",
148            ModuleCodes::MODULE_CODE_SECTIONNAME => "SECTIONNAME",
149            ModuleCodes::MODULE_CODE_DEPLIB => "DEPLIB",
150            ModuleCodes::MODULE_CODE_GLOBALVAR => "GLOBALVAR",
151            ModuleCodes::MODULE_CODE_FUNCTION => "FUNCTION",
152            ModuleCodes::MODULE_CODE_ALIAS => "ALIAS",
153            ModuleCodes::MODULE_CODE_GCNAME => "GCNAME",
154            ModuleCodes::MODULE_CODE_COMDAT => "COMDAT",
155            ModuleCodes::MODULE_CODE_VSTOFFSET => "VSTOFFSET",
156            ModuleCodes::MODULE_CODE_METADATA_VALUES_UNUSED => "METADATA_VALUES_UNUSED",
157            ModuleCodes::MODULE_CODE_SOURCE_FILENAME => "SOURCE_FILENAME",
158            ModuleCodes::MODULE_CODE_HASH => "HASH",
159            ModuleCodes::MODULE_CODE_ALIAS_OLD | ModuleCodes::MODULE_CODE_IFUNC => todo!(),
160        },
161        Blocks::IDENTIFICATION_BLOCK_ID => match IdentificationCodes::try_from(record).unwrap() {
162            IdentificationCodes::IDENTIFICATION_CODE_STRING => "STRING",
163            IdentificationCodes::IDENTIFICATION_CODE_EPOCH => "EPOCH",
164        },
165        crate::Blocks::PARAMATTR_GROUP_BLOCK_ID | crate::Blocks::PARAMATTR_BLOCK_ID => {
166            match AttributeCodes::try_from(record).unwrap() {
167                AttributeCodes::PARAMATTR_CODE_ENTRY_OLD => "ENTRY_OLD",
168                AttributeCodes::PARAMATTR_CODE_ENTRY => "ENTRY",
169                AttributeCodes::PARAMATTR_GRP_CODE_ENTRY => "ENTRY",
170            }
171        }
172        Blocks::TYPE_BLOCK_ID_NEW => match TypeCodes::try_from(record).unwrap() {
173            TypeCodes::TYPE_CODE_NUMENTRY => "NUMENTRY",
174            TypeCodes::TYPE_CODE_VOID => "VOID",
175            TypeCodes::TYPE_CODE_FLOAT => "FLOAT",
176            TypeCodes::TYPE_CODE_DOUBLE => "DOUBLE",
177            TypeCodes::TYPE_CODE_LABEL => "LABEL",
178            TypeCodes::TYPE_CODE_OPAQUE => "OPAQUE",
179            TypeCodes::TYPE_CODE_INTEGER => "INTEGER",
180            TypeCodes::TYPE_CODE_POINTER => "POINTER",
181            TypeCodes::TYPE_CODE_HALF => "HALF",
182            TypeCodes::TYPE_CODE_ARRAY => "ARRAY",
183            TypeCodes::TYPE_CODE_VECTOR => "VECTOR",
184            TypeCodes::TYPE_CODE_X86_FP80 => "X86_FP80",
185            TypeCodes::TYPE_CODE_FP128 => "FP128",
186            TypeCodes::TYPE_CODE_PPC_FP128 => "PPC_FP128",
187            TypeCodes::TYPE_CODE_METADATA => "METADATA",
188            TypeCodes::TYPE_CODE_X86_MMX => "X86_MMX",
189            TypeCodes::TYPE_CODE_STRUCT_ANON => "STRUCT_ANON",
190            TypeCodes::TYPE_CODE_STRUCT_NAME => "STRUCT_NAME",
191            TypeCodes::TYPE_CODE_STRUCT_NAMED => "STRUCT_NAMED",
192            TypeCodes::TYPE_CODE_FUNCTION => "FUNCTION",
193            TypeCodes::TYPE_CODE_TOKEN => "TOKEN",
194            TypeCodes::TYPE_CODE_BFLOAT => "BFLOAT",
195            TypeCodes::TYPE_CODE_FUNCTION_OLD => "FUNCTION_OLD",
196            TypeCodes::TYPE_CODE_X86_AMX => "X86_AMX",
197            TypeCodes::TYPE_CODE_OPAQUE_POINTER => "UnknownCode25", //"OPAQUE_POINTER",
198            TypeCodes::TYPE_CODE_TARGET_TYPE => "TARGET_TYPE",
199        },
200        Blocks::CONSTANTS_BLOCK_ID => match ConstantsCodes::try_from(record).unwrap() {
201            ConstantsCodes::CST_CODE_SETTYPE => "SETTYPE",
202            ConstantsCodes::CST_CODE_NULL => "NULL",
203            ConstantsCodes::CST_CODE_UNDEF => "UNDEF",
204            ConstantsCodes::CST_CODE_INTEGER => "INTEGER",
205            ConstantsCodes::CST_CODE_WIDE_INTEGER => "WIDE_INTEGER",
206            ConstantsCodes::CST_CODE_FLOAT => "FLOAT",
207            ConstantsCodes::CST_CODE_AGGREGATE => "AGGREGATE",
208            ConstantsCodes::CST_CODE_STRING => "STRING",
209            ConstantsCodes::CST_CODE_CSTRING => "CSTRING",
210            ConstantsCodes::CST_CODE_CE_BINOP => "CE_BINOP",
211            ConstantsCodes::CST_CODE_CE_CAST => "CE_CAST",
212            ConstantsCodes::CST_CODE_CE_GEP => "CE_GEP",
213            ConstantsCodes::CST_CODE_CE_INBOUNDS_GEP => "CE_INBOUNDS_GEP",
214            ConstantsCodes::CST_CODE_CE_SELECT => "CE_SELECT",
215            ConstantsCodes::CST_CODE_CE_EXTRACTELT => "CE_EXTRACTELT",
216            ConstantsCodes::CST_CODE_CE_INSERTELT => "CE_INSERTELT",
217            ConstantsCodes::CST_CODE_CE_SHUFFLEVEC => "CE_SHUFFLEVEC",
218            ConstantsCodes::CST_CODE_CE_CMP => "CE_CMP",
219            ConstantsCodes::CST_CODE_INLINEASM => "INLINEASM",
220            ConstantsCodes::CST_CODE_CE_SHUFVEC_EX => "CE_SHUFVEC_EX",
221            ConstantsCodes::CST_CODE_CE_UNOP => "CE_UNOP",
222            ConstantsCodes::CST_CODE_DSO_LOCAL_EQUIVALENT => "DSO_LOCAL_EQUIVALENT",
223            ConstantsCodes::CST_CODE_NO_CFI_VALUE => "NO_CFI_VALUE",
224            ConstantsCodes::CST_CODE_PTRAUTH => "PTRAUTH",
225            ConstantsCodes::CST_CODE_BLOCKADDRESS => "BLOCKADDRESS",
226            ConstantsCodes::CST_CODE_DATA => "DATA",
227            ConstantsCodes::CST_CODE_CE_GEP_OLD => "CE_GEP_OLD",
228            ConstantsCodes::CST_CODE_INLINEASM_OLD => "INLINEASM_OLD",
229            ConstantsCodes::CST_CODE_INLINEASM_OLD2 => "INLINEASM_OLD2",
230            ConstantsCodes::CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD => {
231                "CE_GEP_WITH_INRANGE_INDEX_OLD"
232            }
233            ConstantsCodes::CST_CODE_POISON => "UnknownCode26", //"POISON",
234            ConstantsCodes::CST_CODE_INLINEASM_OLD3 => "INLINEASM_OLD3",
235            ConstantsCodes::CST_CODE_CE_GEP_WITH_INRANGE => "CE_GEP_WITH_INRANGE",
236        },
237        Blocks::FUNCTION_BLOCK_ID => match FunctionCodes::try_from(record).unwrap() {
238            FunctionCodes::FUNC_CODE_DECLAREBLOCKS => "DECLAREBLOCKS",
239            FunctionCodes::FUNC_CODE_INST_BINOP => "INST_BINOP",
240            FunctionCodes::FUNC_CODE_INST_CAST => "INST_CAST",
241            FunctionCodes::FUNC_CODE_INST_GEP_OLD => "INST_GEP_OLD",
242            FunctionCodes::FUNC_CODE_INST_INBOUNDS_GEP_OLD => "INST_INBOUNDS_GEP_OLD",
243            FunctionCodes::FUNC_CODE_INST_SELECT => "INST_SELECT",
244            FunctionCodes::FUNC_CODE_INST_EXTRACTELT => "INST_EXTRACTELT",
245            FunctionCodes::FUNC_CODE_INST_INSERTELT => "INST_INSERTELT",
246            FunctionCodes::FUNC_CODE_INST_SHUFFLEVEC => "INST_SHUFFLEVEC",
247            FunctionCodes::FUNC_CODE_INST_CMP => "INST_CMP",
248            FunctionCodes::FUNC_CODE_INST_RET => "INST_RET",
249            FunctionCodes::FUNC_CODE_INST_BR => "INST_BR",
250            FunctionCodes::FUNC_CODE_INST_SWITCH => "INST_SWITCH",
251            FunctionCodes::FUNC_CODE_INST_INVOKE => "INST_INVOKE",
252            FunctionCodes::FUNC_CODE_INST_UNOP => "INST_UNOP",
253            FunctionCodes::FUNC_CODE_INST_UNREACHABLE => "INST_UNREACHABLE",
254            FunctionCodes::FUNC_CODE_INST_CLEANUPRET => "INST_CLEANUPRET",
255            FunctionCodes::FUNC_CODE_INST_CATCHRET => "INST_CATCHRET",
256            FunctionCodes::FUNC_CODE_INST_CATCHPAD => "INST_CATCHPAD",
257            FunctionCodes::FUNC_CODE_INST_PHI => "INST_PHI",
258            FunctionCodes::FUNC_CODE_INST_ALLOCA => "INST_ALLOCA",
259            FunctionCodes::FUNC_CODE_INST_LOAD => "INST_LOAD",
260            FunctionCodes::FUNC_CODE_INST_VAARG => "INST_VAARG",
261            FunctionCodes::FUNC_CODE_INST_STORE => "INST_STORE",
262            FunctionCodes::FUNC_CODE_INST_EXTRACTVAL => "INST_EXTRACTVAL",
263            FunctionCodes::FUNC_CODE_INST_INSERTVAL => "INST_INSERTVAL",
264            FunctionCodes::FUNC_CODE_INST_CMP2 => "INST_CMP2",
265            FunctionCodes::FUNC_CODE_INST_VSELECT => "INST_VSELECT",
266            FunctionCodes::FUNC_CODE_DEBUG_LOC_AGAIN => "DEBUG_LOC_AGAIN",
267            FunctionCodes::FUNC_CODE_INST_CALL => "INST_CALL",
268            FunctionCodes::FUNC_CODE_DEBUG_LOC => "DEBUG_LOC",
269            FunctionCodes::FUNC_CODE_INST_GEP => "INST_GEP",
270            FunctionCodes::FUNC_CODE_OPERAND_BUNDLE => "OPERAND_BUNDLE",
271            FunctionCodes::FUNC_CODE_INST_FENCE => "INST_FENCE",
272            FunctionCodes::FUNC_CODE_INST_ATOMICRMW => "INST_ATOMICRMW",
273            FunctionCodes::FUNC_CODE_INST_LOADATOMIC => "INST_LOADATOMIC",
274            FunctionCodes::FUNC_CODE_INST_STOREATOMIC => "INST_STOREATOMIC",
275            FunctionCodes::FUNC_CODE_INST_CMPXCHG => "INST_CMPXCHG",
276            FunctionCodes::FUNC_CODE_INST_CALLBR => "INST_CALLBR",
277            FunctionCodes::FUNC_CODE_BLOCKADDR_USERS => "BLOCKADDR_USERS",
278            FunctionCodes::FUNC_CODE_DEBUG_RECORD_DECLARE => "DEBUG_RECORD_DECLARE",
279            FunctionCodes::FUNC_CODE_DEBUG_RECORD_VALUE => "DEBUG_RECORD_VALUE",
280            FunctionCodes::FUNC_CODE_DEBUG_RECORD_ASSIGN => "DEBUG_RECORD_ASSIGN",
281            FunctionCodes::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE => "DEBUG_RECORD_VALUE_SIMPLE",
282            FunctionCodes::FUNC_CODE_DEBUG_RECORD_LABEL => "DEBUG_RECORD_LABEL",
283
284            FunctionCodes::FUNC_CODE_INST_STORE_OLD => "INST_STORE_OLD",
285            FunctionCodes::FUNC_CODE_INST_INDIRECTBR => "INST_INDIRECTBR",
286            FunctionCodes::FUNC_CODE_INST_CMPXCHG_OLD => "INST_CMPXCHG_OLD",
287            FunctionCodes::FUNC_CODE_INST_ATOMICRMW_OLD => "INST_ATOMICRMW_OLD",
288            FunctionCodes::FUNC_CODE_INST_RESUME => "UnknownCode39", //"INST_RESUME",
289            FunctionCodes::FUNC_CODE_INST_LANDINGPAD_OLD => "INST_LANDINGPAD_OLD",
290            FunctionCodes::FUNC_CODE_INST_STOREATOMIC_OLD => "INST_STOREATOMIC_OLD",
291            FunctionCodes::FUNC_CODE_INST_LANDINGPAD => "UnknownCode47", //"INST_LANDINGPAD",
292            FunctionCodes::FUNC_CODE_INST_CLEANUPPAD => "INST_CLEANUPPAD",
293            FunctionCodes::FUNC_CODE_INST_CATCHSWITCH => "INST_CATCHSWITCH",
294            FunctionCodes::FUNC_CODE_INST_FREEZE => "INST_FREEZE",
295        },
296        Blocks::VALUE_SYMTAB_BLOCK_ID => match ValueSymtabCodes::try_from(record).unwrap() {
297            ValueSymtabCodes::VST_CODE_ENTRY => "ENTRY",
298            ValueSymtabCodes::VST_CODE_BBENTRY => "BBENTRY",
299            ValueSymtabCodes::VST_CODE_FNENTRY => "FNENTRY",
300            ValueSymtabCodes::VST_CODE_COMBINED_ENTRY => "COMBINED_ENTRY",
301        },
302        Blocks::MODULE_STRTAB_BLOCK_ID => match ModulePathSymtabCodes::try_from(record).unwrap() {
303            ModulePathSymtabCodes::MST_CODE_ENTRY => "ENTRY",
304            ModulePathSymtabCodes::MST_CODE_HASH => "HASH",
305        },
306        crate::Blocks::GLOBALVAL_SUMMARY_BLOCK_ID
307        | crate::Blocks::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID => {
308            match GlobalValueSummarySymtabCodes::try_from(record).unwrap() {
309                GlobalValueSummarySymtabCodes::FS_PERMODULE => "PERMODULE",
310                GlobalValueSummarySymtabCodes::FS_PERMODULE_PROFILE => "PERMODULE_PROFILE",
311                GlobalValueSummarySymtabCodes::FS_PERMODULE_RELBF => "PERMODULE_RELBF",
312                GlobalValueSummarySymtabCodes::FS_PERMODULE_GLOBALVAR_INIT_REFS => {
313                    "PERMODULE_GLOBALVAR_INIT_REFS"
314                }
315                GlobalValueSummarySymtabCodes::FS_PERMODULE_VTABLE_GLOBALVAR_INIT_REFS => {
316                    "PERMODULE_VTABLE_GLOBALVAR_INIT_REFS"
317                }
318                GlobalValueSummarySymtabCodes::FS_COMBINED => "COMBINED",
319                GlobalValueSummarySymtabCodes::FS_COMBINED_PROFILE => "COMBINED_PROFILE",
320                GlobalValueSummarySymtabCodes::FS_COMBINED_GLOBALVAR_INIT_REFS => {
321                    "COMBINED_GLOBALVAR_INIT_REFS"
322                }
323                GlobalValueSummarySymtabCodes::FS_ALIAS => "ALIAS",
324                GlobalValueSummarySymtabCodes::FS_COMBINED_ALIAS => "COMBINED_ALIAS",
325                GlobalValueSummarySymtabCodes::FS_COMBINED_ORIGINAL_NAME => {
326                    "COMBINED_ORIGINAL_NAME"
327                }
328                GlobalValueSummarySymtabCodes::FS_VERSION => "VERSION",
329                GlobalValueSummarySymtabCodes::FS_FLAGS => "FLAGS",
330                GlobalValueSummarySymtabCodes::FS_TYPE_TESTS => "TYPE_TESTS",
331                GlobalValueSummarySymtabCodes::FS_TYPE_TEST_ASSUME_VCALLS => {
332                    "TYPE_TEST_ASSUME_VCALLS"
333                }
334                GlobalValueSummarySymtabCodes::FS_TYPE_CHECKED_LOAD_VCALLS => {
335                    "TYPE_CHECKED_LOAD_VCALLS"
336                }
337                GlobalValueSummarySymtabCodes::FS_TYPE_TEST_ASSUME_CONST_VCALL => {
338                    "TYPE_TEST_ASSUME_CONST_VCALL"
339                }
340                GlobalValueSummarySymtabCodes::FS_TYPE_CHECKED_LOAD_CONST_VCALL => {
341                    "TYPE_CHECKED_LOAD_CONST_VCALL"
342                }
343                GlobalValueSummarySymtabCodes::FS_VALUE_GUID => "VALUE_GUID",
344                GlobalValueSummarySymtabCodes::FS_CFI_FUNCTION_DEFS => "CFI_FUNCTION_DEFS",
345                GlobalValueSummarySymtabCodes::FS_CFI_FUNCTION_DECLS => "CFI_FUNCTION_DECLS",
346                GlobalValueSummarySymtabCodes::FS_TYPE_ID => "TYPE_ID",
347                GlobalValueSummarySymtabCodes::FS_TYPE_ID_METADATA => "TYPE_ID_METADATA",
348                GlobalValueSummarySymtabCodes::FS_BLOCK_COUNT => "BLOCK_COUNT",
349                GlobalValueSummarySymtabCodes::FS_PARAM_ACCESS => "PARAM_ACCESS",
350                GlobalValueSummarySymtabCodes::FS_PERMODULE_CALLSITE_INFO => {
351                    "PERMODULE_CALLSITE_INFO"
352                }
353                GlobalValueSummarySymtabCodes::FS_PERMODULE_ALLOC_INFO => "PERMODULE_ALLOC_INFO",
354                GlobalValueSummarySymtabCodes::FS_COMBINED_CALLSITE_INFO => {
355                    "COMBINED_CALLSITE_INFO"
356                }
357                GlobalValueSummarySymtabCodes::FS_COMBINED_ALLOC_INFO => "COMBINED_ALLOC_INFO",
358                GlobalValueSummarySymtabCodes::FS_STACK_IDS => "STACK_IDS",
359                GlobalValueSummarySymtabCodes::FS_ALLOC_CONTEXT_IDS => "ALLOC_CONTEXT_IDS",
360                GlobalValueSummarySymtabCodes::FS_CONTEXT_RADIX_TREE_ARRAY => {
361                    "CONTEXT_RADIX_TREE_ARRAY"
362                }
363            }
364        }
365        crate::Blocks::METADATA_KIND_BLOCK_ID
366        | crate::Blocks::METADATA_BLOCK_ID
367        | Blocks::METADATA_ATTACHMENT_ID => match MetadataCodes::try_from(record).unwrap() {
368            MetadataCodes::METADATA_ATTACHMENT => "ATTACHMENT",
369            MetadataCodes::METADATA_STRING_OLD => "STRING_OLD",
370            MetadataCodes::METADATA_VALUE => "VALUE",
371            MetadataCodes::METADATA_NODE => "NODE",
372            MetadataCodes::METADATA_NAME => "NAME",
373            MetadataCodes::METADATA_DISTINCT_NODE => "DISTINCT_NODE",
374            MetadataCodes::METADATA_KIND => "KIND",
375            MetadataCodes::METADATA_LOCATION => "LOCATION",
376            MetadataCodes::METADATA_OLD_NODE => "OLD_NODE",
377            MetadataCodes::METADATA_OLD_FN_NODE => "OLD_FN_NODE",
378            MetadataCodes::METADATA_NAMED_NODE => "NAMED_NODE",
379            MetadataCodes::METADATA_GENERIC_DEBUG => "GENERIC_DEBUG",
380            MetadataCodes::METADATA_SUBRANGE => "SUBRANGE",
381            MetadataCodes::METADATA_ENUMERATOR => "ENUMERATOR",
382            MetadataCodes::METADATA_BASIC_TYPE => "BASIC_TYPE",
383            MetadataCodes::METADATA_FILE => "FILE",
384            MetadataCodes::METADATA_DERIVED_TYPE => "DERIVED_TYPE",
385            MetadataCodes::METADATA_COMPOSITE_TYPE => "COMPOSITE_TYPE",
386            MetadataCodes::METADATA_SUBROUTINE_TYPE => "SUBROUTINE_TYPE",
387            MetadataCodes::METADATA_COMPILE_UNIT => "COMPILE_UNIT",
388            MetadataCodes::METADATA_SUBPROGRAM => "SUBPROGRAM",
389            MetadataCodes::METADATA_LEXICAL_BLOCK => "LEXICAL_BLOCK",
390            MetadataCodes::METADATA_LEXICAL_BLOCK_FILE => "LEXICAL_BLOCK_FILE",
391            MetadataCodes::METADATA_NAMESPACE => "NAMESPACE",
392            MetadataCodes::METADATA_TEMPLATE_TYPE => "TEMPLATE_TYPE",
393            MetadataCodes::METADATA_TEMPLATE_VALUE => "TEMPLATE_VALUE",
394            MetadataCodes::METADATA_GLOBAL_VAR => "GLOBAL_VAR",
395            MetadataCodes::METADATA_LOCAL_VAR => "LOCAL_VAR",
396            MetadataCodes::METADATA_EXPRESSION => "EXPRESSION",
397            MetadataCodes::METADATA_OBJC_PROPERTY => "OBJC_PROPERTY",
398            MetadataCodes::METADATA_IMPORTED_ENTITY => "IMPORTED_ENTITY",
399            MetadataCodes::METADATA_MODULE => "MODULE",
400            MetadataCodes::METADATA_MACRO => "MACRO",
401            MetadataCodes::METADATA_MACRO_FILE => "MACRO_FILE",
402            MetadataCodes::METADATA_STRINGS => "STRINGS",
403            MetadataCodes::METADATA_GLOBAL_DECL_ATTACHMENT => "GLOBAL_DECL_ATTACHMENT",
404            MetadataCodes::METADATA_GLOBAL_VAR_EXPR => "GLOBAL_VAR_EXPR",
405            MetadataCodes::METADATA_INDEX_OFFSET => "INDEX_OFFSET",
406            MetadataCodes::METADATA_INDEX => "INDEX",
407            MetadataCodes::METADATA_ARG_LIST => "ARG_LIST",
408            MetadataCodes::METADATA_LABEL => "LABEL",
409            MetadataCodes::METADATA_STRING_TYPE => "STRING_TYPE",
410            MetadataCodes::METADATA_COMMON_BLOCK => "COMMON_BLOCK",
411            MetadataCodes::METADATA_GENERIC_SUBRANGE => "GENERIC_SUBRANGE",
412            MetadataCodes::METADATA_ASSIGN_ID => "ASSIGN_ID",
413        },
414        Blocks::USELIST_BLOCK_ID => match UseListCodes::try_from(record).unwrap() {
415            UseListCodes::USELIST_CODE_DEFAULT => "DEFAULT",
416            UseListCodes::USELIST_CODE_BB => "BB",
417        },
418        Blocks::OPERAND_BUNDLE_TAGS_BLOCK_ID => {
419            match OperandBundleTagCode::try_from(record).unwrap() {
420                OperandBundleTagCode::OPERAND_BUNDLE_TAG => "OPERAND_BUNDLE_TAG",
421            }
422        }
423        Blocks::STRTAB_BLOCK_ID => match StrtabCodes::try_from(record).unwrap() {
424            StrtabCodes::STRTAB_BLOB => "BLOB",
425        },
426        Blocks::SYMTAB_BLOCK_ID => match SymtabCodes::try_from(record).unwrap() {
427            SymtabCodes::SYMTAB_BLOB => "BLOB",
428        },
429        Blocks::SYNC_SCOPE_NAMES_BLOCK_ID => "UnknownCode1",
430    }
431}
432
433#[derive(TryFromPrimitive)]
434#[repr(u32)]
435enum Blocks {
436    MODULE_BLOCK_ID = 8,
437    PARAMATTR_BLOCK_ID,
438    PARAMATTR_GROUP_BLOCK_ID,
439    CONSTANTS_BLOCK_ID,
440    FUNCTION_BLOCK_ID,
441    IDENTIFICATION_BLOCK_ID,
442    VALUE_SYMTAB_BLOCK_ID,
443    METADATA_BLOCK_ID,
444    METADATA_ATTACHMENT_ID,
445    TYPE_BLOCK_ID_NEW,
446    USELIST_BLOCK_ID,
447    MODULE_STRTAB_BLOCK_ID,
448    GLOBALVAL_SUMMARY_BLOCK_ID,
449    OPERAND_BUNDLE_TAGS_BLOCK_ID,
450    METADATA_KIND_BLOCK_ID,
451    STRTAB_BLOCK_ID,
452    FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID,
453    SYMTAB_BLOCK_ID,
454    SYNC_SCOPE_NAMES_BLOCK_ID,
455}
456
457/// Identification block contains a string that describes the producer details,
458/// and an epoch that defines the auto-upgrade capability.
459#[derive(TryFromPrimitive)]
460#[repr(u32)]
461enum IdentificationCodes {
462    IDENTIFICATION_CODE_STRING = 1, // IDENTIFICATION:      [strchr x N]
463    IDENTIFICATION_CODE_EPOCH = 2,  // EPOCH:               [epoch#]
464}
465
466/// The epoch that defines the auto-upgrade compatibility for the bitcode.
467///
468/// LLVM guarantees in a major release that a minor release can read bitcode
469/// generated by previous minor releases. We translate this by making the reader
470/// accepting only bitcode with the same epoch, except for the X.0 release which
471/// also accepts N-1.
472#[derive(TryFromPrimitive)]
473#[repr(u32)]
474enum EpochCode {
475    BITCODE_CURRENT_EPOCH = 0,
476}
477
478/// MODULE blocks have a number of optional fields and subblocks.
479#[derive(TryFromPrimitive)]
480#[repr(u32)]
481enum ModuleCodes {
482    MODULE_CODE_VERSION = 1,     // VERSION:     [version#]
483    MODULE_CODE_TRIPLE = 2,      // TRIPLE:      [strchr x N]
484    MODULE_CODE_DATALAYOUT = 3,  // DATALAYOUT:  [strchr x N]
485    MODULE_CODE_ASM = 4,         // ASM:         [strchr x N]
486    MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N]
487
488    // Deprecated, but still needed to read old bitcode files.
489    MODULE_CODE_DEPLIB = 6, // DEPLIB:      [strchr x N]
490
491    // GLOBALVAR: [pointer type, isconst, initid,
492    //             linkage, alignment, section, visibility, threadlocal]
493    MODULE_CODE_GLOBALVAR = 7,
494
495    // FUNCTION:  [type, callingconv, isproto, linkage, paramattrs, alignment,
496    //             section, visibility, gc, unnamed_addr]
497    MODULE_CODE_FUNCTION = 8,
498
499    // ALIAS: [alias type, aliasee val#, linkage, visibility]
500    MODULE_CODE_ALIAS_OLD = 9,
501
502    MODULE_CODE_GCNAME = 11, // GCNAME: [strchr x N]
503    MODULE_CODE_COMDAT = 12, // COMDAT: [selection_kind, name]
504
505    MODULE_CODE_VSTOFFSET = 13, // VSTOFFSET: [offset]
506
507    // ALIAS: [alias value type, addrspace, aliasee val#, linkage, visibility]
508    MODULE_CODE_ALIAS = 14,
509
510    MODULE_CODE_METADATA_VALUES_UNUSED = 15,
511
512    // SOURCE_FILENAME: [namechar x N]
513    MODULE_CODE_SOURCE_FILENAME = 16,
514
515    // HASH: [5*i32]
516    MODULE_CODE_HASH = 17,
517
518    // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility]
519    MODULE_CODE_IFUNC = 18,
520}
521
522/// PARAMATTR blocks have code for defining a parameter attribute set.
523#[derive(TryFromPrimitive)]
524#[repr(u32)]
525enum AttributeCodes {
526    // Deprecated, but still needed to read old bitcode files.
527    PARAMATTR_CODE_ENTRY_OLD = 1, // ENTRY: [paramidx0, attr0,
528    //         paramidx1, attr1...]
529    PARAMATTR_CODE_ENTRY = 2,     // ENTRY: [attrgrp0, attrgrp1, ...]
530    PARAMATTR_GRP_CODE_ENTRY = 3, // ENTRY: [grpid, idx, attr0, attr1, ...]
531}
532
533/// TYPE blocks have codes for each type primitive they use.
534#[derive(TryFromPrimitive)]
535#[repr(u32)]
536enum TypeCodes {
537    TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries]
538
539    // Type Codes
540    TYPE_CODE_VOID = 2,    // VOID
541    TYPE_CODE_FLOAT = 3,   // FLOAT
542    TYPE_CODE_DOUBLE = 4,  // DOUBLE
543    TYPE_CODE_LABEL = 5,   // LABEL
544    TYPE_CODE_OPAQUE = 6,  // OPAQUE
545    TYPE_CODE_INTEGER = 7, // INTEGER: [width]
546    TYPE_CODE_POINTER = 8, // POINTER: [pointee type]
547
548    TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty,
549    //            paramty x N]
550    TYPE_CODE_HALF = 10, // HALF
551
552    TYPE_CODE_ARRAY = 11,  // ARRAY: [num_elements, elements_type]
553    TYPE_CODE_VECTOR = 12, // VECTOR: [num_elements, elements_type]
554
555    // These are not with the other floating point types because they're
556    // a late addition, and putting them in the right place breaks
557    // binary compatibility.
558    TYPE_CODE_X86_FP80 = 13,  // X86 LONG DOUBLE
559    TYPE_CODE_FP128 = 14,     // LONG DOUBLE (112 bit mantissa)
560    TYPE_CODE_PPC_FP128 = 15, // PPC LONG DOUBLE (2 doubles)
561
562    TYPE_CODE_METADATA = 16, // METADATA
563
564    TYPE_CODE_X86_MMX = 17, // X86 MMX
565
566    TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, elements_type x N]
567    TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N]
568    TYPE_CODE_STRUCT_NAMED = 20, // STRUCT_NAMED: [ispacked, elements_type x N]
569
570    TYPE_CODE_FUNCTION = 21, // FUNCTION: [vararg, retty, paramty x N]
571
572    TYPE_CODE_TOKEN = 22, // TOKEN
573
574    TYPE_CODE_BFLOAT = 23,  // BRAIN FLOATING POINT
575    TYPE_CODE_X86_AMX = 24, // X86 AMX
576
577    TYPE_CODE_OPAQUE_POINTER = 25, // OPAQUE_POINTER: [addrspace]
578
579    TYPE_CODE_TARGET_TYPE = 26, // TARGET_TYPE
580}
581
582#[derive(TryFromPrimitive)]
583#[repr(u32)]
584enum OperandBundleTagCode {
585    OPERAND_BUNDLE_TAG = 1, // TAG: [strchr x N]
586}
587
588#[derive(TryFromPrimitive)]
589#[repr(u32)]
590enum SyncScopeNameCode {
591    SYNC_SCOPE_NAME = 1,
592}
593
594// Value symbol table codes.
595#[derive(TryFromPrimitive)]
596#[repr(u32)]
597enum ValueSymtabCodes {
598    VST_CODE_ENTRY = 1,   // VST_ENTRY: [valueid, namechar x N]
599    VST_CODE_BBENTRY = 2, // VST_BBENTRY: [bbid, namechar x N]
600    VST_CODE_FNENTRY = 3, // VST_FNENTRY: [valueid, offset, namechar x N]
601    // VST_COMBINED_ENTRY: [valueid, refguid]
602    VST_CODE_COMBINED_ENTRY = 5,
603}
604
605// The module path symbol table only has one code (MST_CODE_ENTRY).
606#[derive(TryFromPrimitive)]
607#[repr(u32)]
608enum ModulePathSymtabCodes {
609    MST_CODE_ENTRY = 1, // MST_ENTRY: [modid, namechar x N]
610    MST_CODE_HASH = 2,  // MST_HASH:  [5*i32]
611}
612
613// The summary section uses different codes in the per-module
614// and combined index cases.
615#[derive(TryFromPrimitive)]
616#[repr(u32)]
617enum GlobalValueSummarySymtabCodes {
618    // PERMODULE: [valueid, flags, instcount, numrefs, numrefs x valueid,
619    //             n x (valueid)]
620    FS_PERMODULE = 1,
621    // PERMODULE_PROFILE: [valueid, flags, instcount, numrefs,
622    //                     numrefs x valueid,
623    //                     n x (valueid, hotness+tailcall)]
624    FS_PERMODULE_PROFILE = 2,
625    // PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, n x valueid]
626    FS_PERMODULE_GLOBALVAR_INIT_REFS = 3,
627    // COMBINED: [valueid, modid, flags, instcount, numrefs, numrefs x valueid,
628    //            n x (valueid)]
629    FS_COMBINED = 4,
630    // COMBINED_PROFILE: [valueid, modid, flags, instcount, numrefs,
631    //                    numrefs x valueid,
632    //                    n x (valueid, hotness+tailcall)]
633    FS_COMBINED_PROFILE = 5,
634    // COMBINED_GLOBALVAR_INIT_REFS: [valueid, modid, flags, n x valueid]
635    FS_COMBINED_GLOBALVAR_INIT_REFS = 6,
636    // ALIAS: [valueid, flags, valueid]
637    FS_ALIAS = 7,
638    // COMBINED_ALIAS: [valueid, modid, flags, valueid]
639    FS_COMBINED_ALIAS = 8,
640    // COMBINED_ORIGINAL_NAME: [original_name_hash]
641    FS_COMBINED_ORIGINAL_NAME = 9,
642    // VERSION of the summary, bumped when adding flags for instance.
643    FS_VERSION = 10,
644    // The list of llvm.type.test type identifiers used by the following function
645    // that are used other than by an llvm.assume.
646    // [n x typeid]
647    FS_TYPE_TESTS = 11,
648    // The list of virtual calls made by this function using
649    // llvm.assume(llvm.type.test) intrinsics that do not have all constant
650    // integer arguments.
651    // [n x (typeid, offset)]
652    FS_TYPE_TEST_ASSUME_VCALLS = 12,
653    // The list of virtual calls made by this function using
654    // llvm.type.checked.load intrinsics that do not have all constant integer
655    // arguments.
656    // [n x (typeid, offset)]
657    FS_TYPE_CHECKED_LOAD_VCALLS = 13,
658    // Identifies a virtual call made by this function using an
659    // llvm.assume(llvm.type.test) intrinsic with all constant integer arguments.
660    // [typeid, offset, n x arg]
661    FS_TYPE_TEST_ASSUME_CONST_VCALL = 14,
662    // Identifies a virtual call made by this function using an
663    // llvm.type.checked.load intrinsic with all constant integer arguments.
664    // [typeid, offset, n x arg]
665    FS_TYPE_CHECKED_LOAD_CONST_VCALL = 15,
666    // Assigns a GUID to a value ID. This normally appears only in combined
667    // summaries, but it can also appear in per-module summaries for PGO data.
668    // [valueid, guid]
669    FS_VALUE_GUID = 16,
670    // The list of local functions with CFI jump tables. Function names are
671    // strings in strtab.
672    // [n * name]
673    FS_CFI_FUNCTION_DEFS = 17,
674    // The list of external functions with CFI jump tables. Function names are
675    // strings in strtab.
676    // [n * name]
677    FS_CFI_FUNCTION_DECLS = 18,
678    // Per-module summary that also adds relative block frequency to callee info.
679    // PERMODULE_RELBF: [valueid, flags, instcount, numrefs,
680    //                   numrefs x valueid,
681    //                   n x (valueid, relblockfreq+tailcall)]
682    FS_PERMODULE_RELBF = 19,
683    // Index-wide flags
684    FS_FLAGS = 20,
685    // Maps type identifier to summary information for that type identifier.
686    // Produced by the thin link (only lives in combined index).
687    // TYPE_ID: [typeid, kind, bitwidth, align, size, bitmask, inlinebits,
688    //           n x (typeid, kind, name, numrba,
689    //                numrba x (numarg, numarg x arg, kind, info, byte, bit))]
690    FS_TYPE_ID = 21,
691    // For background see overview at https://llvm.org/docs/TypeMetadata.html.
692    // The type metadata includes both the type identifier and the offset of
693    // the address point of the type (the address held by objects of that type
694    // which may not be the beginning of the virtual table). Vtable definitions
695    // are decorated with type metadata for the types they are compatible with.
696    //
697    // Maps type identifier to summary information for that type identifier
698    // computed from type metadata: the valueid of each vtable definition
699    // decorated with a type metadata for that identifier, and the offset from
700    // the corresponding type metadata.
701    // Exists in the per-module summary to provide information to thin link
702    // for index-based whole program devirtualization.
703    // TYPE_ID_METADATA: [typeid, n x (valueid, offset)]
704    FS_TYPE_ID_METADATA = 22,
705    // Summarizes vtable definition for use in index-based whole program
706    // devirtualization during the thin link.
707    // PERMODULE_VTABLE_GLOBALVAR_INIT_REFS: [valueid, flags, varflags,
708    //                                        numrefs, numrefs x valueid,
709    //                                        n x (valueid, offset)]
710    FS_PERMODULE_VTABLE_GLOBALVAR_INIT_REFS = 23,
711    // The total number of basic blocks in the module.
712    FS_BLOCK_COUNT = 24,
713    // Range information for accessed offsets for every argument.
714    // [n x (paramno, range, numcalls, numcalls x (callee_guid, paramno, range))]
715    FS_PARAM_ACCESS = 25,
716    // Summary of per-module memprof callsite metadata.
717    // [valueid, n x stackidindex]
718    FS_PERMODULE_CALLSITE_INFO = 26,
719    // Summary of per-module allocation memprof metadata.
720    // [nummib, nummib x (alloc type, context radix tree index),
721    // [nummib x (numcontext x total size)]?]
722    FS_PERMODULE_ALLOC_INFO = 27,
723    // Summary of combined index memprof callsite metadata.
724    // [valueid, context radix tree index, numver,
725    //  numver x version]
726    FS_COMBINED_CALLSITE_INFO = 28,
727    // Summary of combined index allocation memprof metadata.
728    // [nummib, numver,
729    //  nummib x (alloc type, numstackids, numstackids x stackidindex),
730    //  numver x version]
731    FS_COMBINED_ALLOC_INFO = 29,
732    // List of all stack ids referenced by index in the callsite and alloc infos.
733    // [n x stack id]
734    FS_STACK_IDS = 30,
735    // List of all full stack id pairs corresponding to the total sizes recorded
736    // at the end of the alloc info when reporting of hinted bytes is enabled.
737    // We use a fixed-width array, which is more efficient as these ids typically
738    // are close to 64 bits in size. The max fixed width value supported is 32
739    // bits so each 64-bit context id hash is recorded as a pair (upper 32 bits
740    // first). This record must immediately precede the associated alloc info, and
741    // the entries must be in the exact same order as the corresponding sizes.
742    // [nummib x (numcontext x full stack id)]
743    FS_ALLOC_CONTEXT_IDS = 31,
744    // Linearized radix tree of allocation contexts. See the description above the
745    // CallStackRadixTreeBuilder class in ProfileData/MemProf.h for format.
746    // [n x entry]
747    FS_CONTEXT_RADIX_TREE_ARRAY = 32,
748}
749
750#[derive(TryFromPrimitive)]
751#[repr(u32)]
752enum MetadataCodes {
753    METADATA_STRING_OLD = 1,              // MDSTRING:      [values]
754    METADATA_VALUE = 2,                   // VALUE:         [type num, value num]
755    METADATA_NODE = 3,                    // NODE:          [n x md num]
756    METADATA_NAME = 4,                    // STRING:        [values]
757    METADATA_DISTINCT_NODE = 5,           // DISTINCT_NODE: [n x md num]
758    METADATA_KIND = 6,                    // [n x [id, name]]
759    METADATA_LOCATION = 7,                // [distinct, line, col, scope, inlined-at?]
760    METADATA_OLD_NODE = 8,                // OLD_NODE:      [n x (type num, value num)]
761    METADATA_OLD_FN_NODE = 9,             // OLD_FN_NODE:   [n x (type num, value num)]
762    METADATA_NAMED_NODE = 10,             // NAMED_NODE:    [n x mdnodes]
763    METADATA_ATTACHMENT = 11,             // [m x [value, [n x [id, mdnode]]]
764    METADATA_GENERIC_DEBUG = 12,          // [distinct, tag, vers, header, n x md num]
765    METADATA_SUBRANGE = 13,               // [distinct, count, lo]
766    METADATA_ENUMERATOR = 14,             // [isUnsigned|distinct, value, name]
767    METADATA_BASIC_TYPE = 15,             // [distinct, tag, name, size, align, enc]
768    METADATA_FILE = 16,                   // [distinct, filename, directory, checksumkind, checksum]
769    METADATA_DERIVED_TYPE = 17,           // [distinct, ...]
770    METADATA_COMPOSITE_TYPE = 18,         // [distinct, ...]
771    METADATA_SUBROUTINE_TYPE = 19,        // [distinct, flags, types, cc]
772    METADATA_COMPILE_UNIT = 20,           // [distinct, ...]
773    METADATA_SUBPROGRAM = 21,             // [distinct, ...]
774    METADATA_LEXICAL_BLOCK = 22,          // [distinct, scope, file, line, column]
775    METADATA_LEXICAL_BLOCK_FILE = 23,     //[distinct, scope, file, discriminator]
776    METADATA_NAMESPACE = 24,              // [distinct, scope, file, name, line, exportSymbols]
777    METADATA_TEMPLATE_TYPE = 25,          // [distinct, scope, name, type, ...]
778    METADATA_TEMPLATE_VALUE = 26,         // [distinct, scope, name, type, value, ...]
779    METADATA_GLOBAL_VAR = 27,             // [distinct, ...]
780    METADATA_LOCAL_VAR = 28,              // [distinct, ...]
781    METADATA_EXPRESSION = 29,             // [distinct, n x element]
782    METADATA_OBJC_PROPERTY = 30,          // [distinct, name, file, line, ...]
783    METADATA_IMPORTED_ENTITY = 31,        // [distinct, tag, scope, entity, line, name]
784    METADATA_MODULE = 32,                 // [distinct, scope, name, ...]
785    METADATA_MACRO = 33,                  // [distinct, macinfo, line, name, value]
786    METADATA_MACRO_FILE = 34,             // [distinct, macinfo, line, file, ...]
787    METADATA_STRINGS = 35,                // [count, offset] blob([lengths][chars])
788    METADATA_GLOBAL_DECL_ATTACHMENT = 36, // [valueid, n x [id, mdnode]]
789    METADATA_GLOBAL_VAR_EXPR = 37,        // [distinct, var, expr]
790    METADATA_INDEX_OFFSET = 38,           // [offset]
791    METADATA_INDEX = 39,                  // [bitpos]
792    METADATA_LABEL = 40,                  // [distinct, scope, name, file, line]
793    METADATA_STRING_TYPE = 41,            // [distinct, name, size, align,...]
794    // Codes 42 and 43 are reserved for support for Fortran array specific debug
795    // info.
796    METADATA_COMMON_BLOCK = 44, // [distinct, scope, name, variable,...]
797    METADATA_GENERIC_SUBRANGE = 45, // [distinct, count, lo, up, stride]
798    METADATA_ARG_LIST = 46,     // [n x [type num, value num]]
799    METADATA_ASSIGN_ID = 47,    // [distinct, ...]
800}
801
802// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
803// constant and maintains an implicit current type value.
804#[derive(TryFromPrimitive)]
805#[repr(u32)]
806enum ConstantsCodes {
807    CST_CODE_SETTYPE = 1,        // SETTYPE:       [typeid]
808    CST_CODE_NULL = 2,           // NULL
809    CST_CODE_UNDEF = 3,          // UNDEF
810    CST_CODE_INTEGER = 4,        // INTEGER:       [intval]
811    CST_CODE_WIDE_INTEGER = 5,   // WIDE_INTEGER:  [n x intval]
812    CST_CODE_FLOAT = 6,          // FLOAT:         [fpval]
813    CST_CODE_AGGREGATE = 7,      // AGGREGATE:     [n x value number]
814    CST_CODE_STRING = 8,         // STRING:        [values]
815    CST_CODE_CSTRING = 9,        // CSTRING:       [values]
816    CST_CODE_CE_BINOP = 10,      // CE_BINOP:      [opcode, opval, opval]
817    CST_CODE_CE_CAST = 11,       // CE_CAST:       [opcode, opty, opval]
818    CST_CODE_CE_GEP_OLD = 12,    // CE_GEP:        [n x operands]
819    CST_CODE_CE_SELECT = 13,     // CE_SELECT:     [opval, opval, opval]
820    CST_CODE_CE_EXTRACTELT = 14, // CE_EXTRACTELT: [opty, opval, opval]
821    CST_CODE_CE_INSERTELT = 15,  // CE_INSERTELT:  [opval, opval, opval]
822    CST_CODE_CE_SHUFFLEVEC = 16, // CE_SHUFFLEVEC: [opval, opval, opval]
823    CST_CODE_CE_CMP = 17,        // CE_CMP:        [opty, opval, opval, pred]
824    CST_CODE_INLINEASM_OLD = 18, // INLINEASM:     [sideeffect|alignstack,
825    //                 asmstr,conststr]
826    CST_CODE_CE_SHUFVEC_EX = 19, // SHUFVEC_EX:    [opty, opval, opval, opval]
827    CST_CODE_CE_INBOUNDS_GEP = 20, // INBOUNDS_GEP:  [n x operands]
828    CST_CODE_BLOCKADDRESS = 21,  // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#]
829    CST_CODE_DATA = 22,          // DATA:          [n x elements]
830    CST_CODE_INLINEASM_OLD2 = 23, // INLINEASM:     [sideeffect|alignstack|
831    //                 asmdialect,asmstr,conststr]
832    CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD = 24, //  [opty, flags, n x operands]
833    CST_CODE_CE_UNOP = 25,                       // CE_UNOP:      [opcode, opval]
834    CST_CODE_POISON = 26,                        // POISON
835    CST_CODE_DSO_LOCAL_EQUIVALENT = 27,          // DSO_LOCAL_EQUIVALENT [gvty, gv]
836    CST_CODE_INLINEASM_OLD3 = 28,                // INLINEASM:     [sideeffect|alignstack|
837    //                 asmdialect|unwind,
838    //                 asmstr,conststr]
839    CST_CODE_NO_CFI_VALUE = 29, // NO_CFI [ fty, f ]
840    CST_CODE_INLINEASM = 30,    // INLINEASM:     [fnty,
841    //                 sideeffect|alignstack|
842    //                 asmdialect|unwind,
843    //                 asmstr,conststr]
844    CST_CODE_CE_GEP_WITH_INRANGE = 31, // [opty, flags, range, n x operands]
845    CST_CODE_CE_GEP = 32,              // [opty, flags, n x operands]
846    CST_CODE_PTRAUTH = 33,             // [ptr, key, disc, addrdisc]
847}
848
849// The function body block (FUNCTION_BLOCK_ID) describes function bodies.  It
850// can contain a constant block (CONSTANTS_BLOCK_ID).
851#[derive(TryFromPrimitive)]
852#[repr(u32)]
853enum FunctionCodes {
854    FUNC_CODE_DECLAREBLOCKS = 1, // DECLAREBLOCKS: [n]
855
856    FUNC_CODE_INST_BINOP = 2,      // BINOP:      [opcode, ty, opval, opval]
857    FUNC_CODE_INST_CAST = 3,       // CAST:       [opcode, ty, opty, opval]
858    FUNC_CODE_INST_GEP_OLD = 4,    // GEP:        [n x operands]
859    FUNC_CODE_INST_SELECT = 5,     // SELECT:     [ty, opval, opval, opval]
860    FUNC_CODE_INST_EXTRACTELT = 6, // EXTRACTELT: [opty, opval, opval]
861    FUNC_CODE_INST_INSERTELT = 7,  // INSERTELT:  [ty, opval, opval, opval]
862    FUNC_CODE_INST_SHUFFLEVEC = 8, // SHUFFLEVEC: [ty, opval, opval, opval]
863    FUNC_CODE_INST_CMP = 9,        // CMP:        [opty, opval, opval, pred]
864
865    FUNC_CODE_INST_RET = 10,    // RET:        [opty,opval<both optional>]
866    FUNC_CODE_INST_BR = 11,     // BR:         [bb#, bb#, cond] or [bb#]
867    FUNC_CODE_INST_SWITCH = 12, // SWITCH:     [opty, op0, op1, ...]
868    FUNC_CODE_INST_INVOKE = 13, // INVOKE:     [attr, fnty, op0,op1, ...]
869    // 14 is unused.
870    FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
871
872    FUNC_CODE_INST_PHI = 16, // PHI:        [ty, val0,bb0, ...]
873    // 17 is unused.
874    // 18 is unused.
875    FUNC_CODE_INST_ALLOCA = 19, // ALLOCA:     [instty, opty, op, align]
876    FUNC_CODE_INST_LOAD = 20,   // LOAD:       [opty, op, align, vol]
877    // 21 is unused.
878    // 22 is unused.
879    FUNC_CODE_INST_VAARG = 23, // VAARG:      [valistty, valist, instty]
880    // This store code encodes the pointer type, rather than the value type
881    // this is so information only available in the pointer type (e.g. address
882    // spaces) is retained.
883    FUNC_CODE_INST_STORE_OLD = 24, // STORE:      [ptrty,ptr,val, align, vol]
884    // 25 is unused.
885    FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands]
886    FUNC_CODE_INST_INSERTVAL = 27,  // INSERTVAL:  [n x operands]
887    // fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to
888    // support legacy vicmp/vfcmp instructions.
889    FUNC_CODE_INST_CMP2 = 28, // CMP2:       [opty, opval, opval, pred]
890    // new select on i1 or [N x i1]
891    FUNC_CODE_INST_VSELECT = 29, // VSELECT:    [ty,opval,opval,predty,pred]
892    FUNC_CODE_INST_INBOUNDS_GEP_OLD = 30, // INBOUNDS_GEP: [n x operands]
893    FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...]
894    // 32 is unused.
895    FUNC_CODE_DEBUG_LOC_AGAIN = 33, // DEBUG_LOC_AGAIN
896
897    FUNC_CODE_INST_CALL = 34, // CALL:    [attr, cc, fnty, fnid, args...]
898
899    FUNC_CODE_DEBUG_LOC = 35,  // DEBUG_LOC:  [Line,Col,ScopeVal, IAVal]
900    FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope]
901    FUNC_CODE_INST_CMPXCHG_OLD = 37, // CMPXCHG: [ptrty, ptr, cmp, val, vol,
902    //            ordering, synchscope,
903    //            failure_ordering?, weak?]
904    FUNC_CODE_INST_ATOMICRMW_OLD = 38, // ATOMICRMW: [ptrty,ptr,val, operation,
905    //             align, vol,
906    //             ordering, synchscope]
907    FUNC_CODE_INST_RESUME = 39,         // RESUME:     [opval]
908    FUNC_CODE_INST_LANDINGPAD_OLD = 40, // LANDINGPAD: [ty,val,val,num,id0,val0...]
909    FUNC_CODE_INST_LOADATOMIC = 41,     // LOAD: [opty, op, align, vol,
910    //        ordering, synchscope]
911    FUNC_CODE_INST_STOREATOMIC_OLD = 42, // STORE: [ptrty,ptr,val, align, vol
912    //         ordering, synchscope]
913    FUNC_CODE_INST_GEP = 43,         // GEP:  [inbounds, n x operands]
914    FUNC_CODE_INST_STORE = 44,       // STORE: [ptrty,ptr,valty,val, align, vol]
915    FUNC_CODE_INST_STOREATOMIC = 45, // STORE: [ptrty,ptr,val, align, vol
916    FUNC_CODE_INST_CMPXCHG = 46,     // CMPXCHG: [ptrty, ptr, cmp, val, vol,
917    //           success_ordering, synchscope,
918    //           failure_ordering, weak]
919    FUNC_CODE_INST_LANDINGPAD = 47, // LANDINGPAD: [ty,val,num,id0,val0...]
920    FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [val] or [val,bb#]
921    FUNC_CODE_INST_CATCHRET = 49,   // CATCHRET: [val,bb#]
922    FUNC_CODE_INST_CATCHPAD = 50,   // CATCHPAD: [bb#,bb#,num,args...]
923    FUNC_CODE_INST_CLEANUPPAD = 51, // CLEANUPPAD: [num,args...]
924    FUNC_CODE_INST_CATCHSWITCH = 52, // CATCHSWITCH: [num,args...] or [num,args...,bb]
925    // 53 is unused.
926    // 54 is unused.
927    FUNC_CODE_OPERAND_BUNDLE = 55, // OPERAND_BUNDLE: [tag#, value...]
928    FUNC_CODE_INST_UNOP = 56,      // UNOP:       [opcode, ty, opval]
929    FUNC_CODE_INST_CALLBR = 57,    // CALLBR:     [attr, cc, norm, transfs,
930    //              fnty, fnid, args...]
931    FUNC_CODE_INST_FREEZE = 58,    // FREEZE: [opty, opval]
932    FUNC_CODE_INST_ATOMICRMW = 59, // ATOMICRMW: [ptrty, ptr, valty, val,
933    //             operation, align, vol,
934    //             ordering, synchscope]
935    FUNC_CODE_BLOCKADDR_USERS = 60, // BLOCKADDR_USERS: [value...]
936
937    FUNC_CODE_DEBUG_RECORD_VALUE = 61, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata]
938    FUNC_CODE_DEBUG_RECORD_DECLARE = 62, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata]
939    FUNC_CODE_DEBUG_RECORD_ASSIGN = 63, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata,
940    //  DIAssignID, DIExpression (addr), ValueAsMetadata (addr)]
941    FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE = 64, // [DILocation, DILocalVariable, DIExpression, Value]
942    FUNC_CODE_DEBUG_RECORD_LABEL = 65,        // [DILocation, DILabel]
943}
944
945#[derive(TryFromPrimitive)]
946#[repr(u32)]
947enum UseListCodes {
948    USELIST_CODE_DEFAULT = 1, // DEFAULT: [index..., value-id]
949    USELIST_CODE_BB = 2,      // BB: [index..., bb-id]
950}
951
952#[derive(TryFromPrimitive)]
953#[repr(u32)]
954enum AttributeKindCodes {
955    // = 0 is unused
956    ATTR_KIND_ALIGNMENT = 1,
957    ATTR_KIND_ALWAYS_INLINE = 2,
958    ATTR_KIND_BY_VAL = 3,
959    ATTR_KIND_INLINE_HINT = 4,
960    ATTR_KIND_IN_REG = 5,
961    ATTR_KIND_MIN_SIZE = 6,
962    ATTR_KIND_NAKED = 7,
963    ATTR_KIND_NEST = 8,
964    ATTR_KIND_NO_ALIAS = 9,
965    ATTR_KIND_NO_BUILTIN = 10,
966    ATTR_KIND_NO_CAPTURE = 11,
967    ATTR_KIND_NO_DUPLICATE = 12,
968    ATTR_KIND_NO_IMPLICIT_FLOAT = 13,
969    ATTR_KIND_NO_INLINE = 14,
970    ATTR_KIND_NON_LAZY_BIND = 15,
971    ATTR_KIND_NO_RED_ZONE = 16,
972    ATTR_KIND_NO_RETURN = 17,
973    ATTR_KIND_NO_UNWIND = 18,
974    ATTR_KIND_OPTIMIZE_FOR_SIZE = 19,
975    ATTR_KIND_READ_NONE = 20,
976    ATTR_KIND_READ_ONLY = 21,
977    ATTR_KIND_RETURNED = 22,
978    ATTR_KIND_RETURNS_TWICE = 23,
979    ATTR_KIND_S_EXT = 24,
980    ATTR_KIND_STACK_ALIGNMENT = 25,
981    ATTR_KIND_STACK_PROTECT = 26,
982    ATTR_KIND_STACK_PROTECT_REQ = 27,
983    ATTR_KIND_STACK_PROTECT_STRONG = 28,
984    ATTR_KIND_STRUCT_RET = 29,
985    ATTR_KIND_SANITIZE_ADDRESS = 30,
986    ATTR_KIND_SANITIZE_THREAD = 31,
987    ATTR_KIND_SANITIZE_MEMORY = 32,
988    ATTR_KIND_UW_TABLE = 33,
989    ATTR_KIND_Z_EXT = 34,
990    ATTR_KIND_BUILTIN = 35,
991    ATTR_KIND_COLD = 36,
992    ATTR_KIND_OPTIMIZE_NONE = 37,
993    ATTR_KIND_IN_ALLOCA = 38,
994    ATTR_KIND_NON_NULL = 39,
995    ATTR_KIND_JUMP_TABLE = 40,
996    ATTR_KIND_DEREFERENCEABLE = 41,
997    ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42,
998    ATTR_KIND_CONVERGENT = 43,
999    ATTR_KIND_SAFESTACK = 44,
1000    ATTR_KIND_ARGMEMONLY = 45,
1001    ATTR_KIND_SWIFT_SELF = 46,
1002    ATTR_KIND_SWIFT_ERROR = 47,
1003    ATTR_KIND_NO_RECURSE = 48,
1004    ATTR_KIND_INACCESSIBLEMEM_ONLY = 49,
1005    ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50,
1006    ATTR_KIND_ALLOC_SIZE = 51,
1007    ATTR_KIND_WRITEONLY = 52,
1008    ATTR_KIND_SPECULATABLE = 53,
1009    ATTR_KIND_STRICT_FP = 54,
1010    ATTR_KIND_SANITIZE_HWADDRESS = 55,
1011    ATTR_KIND_NOCF_CHECK = 56,
1012    ATTR_KIND_OPT_FOR_FUZZING = 57,
1013    ATTR_KIND_SHADOWCALLSTACK = 58,
1014    ATTR_KIND_SPECULATIVE_LOAD_HARDENING = 59,
1015    ATTR_KIND_IMMARG = 60,
1016    ATTR_KIND_WILLRETURN = 61,
1017    ATTR_KIND_NOFREE = 62,
1018    ATTR_KIND_NOSYNC = 63,
1019    ATTR_KIND_SANITIZE_MEMTAG = 64,
1020    ATTR_KIND_PREALLOCATED = 65,
1021    ATTR_KIND_NO_MERGE = 66,
1022    ATTR_KIND_NULL_POINTER_IS_VALID = 67,
1023    ATTR_KIND_NOUNDEF = 68,
1024    ATTR_KIND_BYREF = 69,
1025    ATTR_KIND_MUSTPROGRESS = 70,
1026    ATTR_KIND_NO_CALLBACK = 71,
1027    ATTR_KIND_HOT = 72,
1028    ATTR_KIND_NO_PROFILE = 73,
1029    ATTR_KIND_VSCALE_RANGE = 74,
1030    ATTR_KIND_SWIFT_ASYNC = 75,
1031    ATTR_KIND_NO_SANITIZE_COVERAGE = 76,
1032    ATTR_KIND_ELEMENTTYPE = 77,
1033    ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION = 78,
1034    ATTR_KIND_NO_SANITIZE_BOUNDS = 79,
1035    ATTR_KIND_ALLOC_ALIGN = 80,
1036    ATTR_KIND_ALLOCATED_POINTER = 81,
1037    ATTR_KIND_ALLOC_KIND = 82,
1038    ATTR_KIND_PRESPLIT_COROUTINE = 83,
1039    ATTR_KIND_FNRETTHUNK_EXTERN = 84,
1040    ATTR_KIND_SKIP_PROFILE = 85,
1041    ATTR_KIND_MEMORY = 86,
1042    ATTR_KIND_NOFPCLASS = 87,
1043    ATTR_KIND_OPTIMIZE_FOR_DEBUGGING = 88,
1044    ATTR_KIND_WRITABLE = 89,
1045    ATTR_KIND_CORO_ONLY_DESTROY_WHEN_COMPLETE = 90,
1046    ATTR_KIND_DEAD_ON_UNWIND = 91,
1047    ATTR_KIND_RANGE = 92,
1048    ATTR_KIND_SANITIZE_NUMERICAL_STABILITY = 93,
1049    ATTR_KIND_INITIALIZES = 94,
1050    ATTR_KIND_HYBRID_PATCHABLE = 95,
1051    ATTR_KIND_SANITIZE_REALTIME = 96,
1052    ATTR_KIND_SANITIZE_REALTIME_BLOCKING = 97,
1053    ATTR_KIND_CORO_ELIDE_SAFE = 98,
1054    ATTR_KIND_NO_EXT = 99,
1055    ATTR_KIND_NO_DIVERGENCE_SOURCE = 100,
1056    ATTR_KIND_SANITIZE_TYPE = 101,
1057    ATTR_KIND_CAPTURES = 102,
1058}
1059
1060#[derive(TryFromPrimitive)]
1061#[repr(u32)]
1062enum ComdatSelectionKindCodes {
1063    COMDAT_SELECTION_KIND_ANY = 1,
1064    COMDAT_SELECTION_KIND_EXACT_MATCH = 2,
1065    COMDAT_SELECTION_KIND_LARGEST = 3,
1066    COMDAT_SELECTION_KIND_NO_DUPLICATES = 4,
1067    COMDAT_SELECTION_KIND_SAME_SIZE = 5,
1068}
1069
1070#[derive(TryFromPrimitive)]
1071#[repr(u32)]
1072enum StrtabCodes {
1073    STRTAB_BLOB = 1,
1074}
1075
1076#[derive(TryFromPrimitive)]
1077#[repr(u32)]
1078enum SymtabCodes {
1079    SYMTAB_BLOB = 1,
1080}