1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2013-2018, Rene Gollent, rene@gollent.com. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 #include "AttributeClasses.h" 8 #include "Dwarf.h" 9 10 11 enum { 12 AC_ADDRESS = 1 << (ATTRIBUTE_CLASS_ADDRESS - 1), 13 AC_BLOCK = 1 << (ATTRIBUTE_CLASS_BLOCK - 1), 14 AC_CONSTANT = 1 << (ATTRIBUTE_CLASS_CONSTANT - 1), 15 AC_FLAG = 1 << (ATTRIBUTE_CLASS_FLAG - 1), 16 AC_LINEPTR = 1 << (ATTRIBUTE_CLASS_LINEPTR - 1), 17 AC_LOCLISTPTR = 1 << (ATTRIBUTE_CLASS_LOCLISTPTR - 1), 18 AC_MACPTR = 1 << (ATTRIBUTE_CLASS_MACPTR - 1), 19 AC_RANGELISTPTR = 1 << (ATTRIBUTE_CLASS_RANGELISTPTR - 1), 20 AC_REFERENCE = 1 << (ATTRIBUTE_CLASS_REFERENCE - 1), 21 AC_STRING = 1 << (ATTRIBUTE_CLASS_STRING - 1) 22 }; 23 24 25 struct attribute_info_entry { 26 const char* name; 27 uint16 value; 28 uint16 classes; 29 }; 30 31 struct attribute_name_info_entry { 32 const char* name; 33 DebugInfoEntrySetter setter; 34 uint16 value; 35 uint16 classes; 36 }; 37 38 39 #undef ENTRY 40 #define ENTRY(name) "DW_AT_" #name, &DebugInfoEntry::AddAttribute_##name, \ 41 DW_AT_##name 42 43 static const attribute_name_info_entry kAttributeNameInfos[] = { 44 { ENTRY(sibling), AC_REFERENCE }, 45 { ENTRY(location), AC_BLOCK | AC_LOCLISTPTR }, 46 { ENTRY(name), AC_STRING }, 47 { ENTRY(ordering), AC_CONSTANT }, 48 { ENTRY(byte_size), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 49 { ENTRY(bit_offset), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 50 { ENTRY(bit_size), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 51 { ENTRY(stmt_list), AC_LINEPTR }, 52 { ENTRY(low_pc), AC_ADDRESS | AC_CONSTANT | AC_REFERENCE }, 53 { ENTRY(high_pc), AC_ADDRESS | AC_CONSTANT | AC_REFERENCE }, 54 { ENTRY(language), AC_CONSTANT }, 55 { ENTRY(discr), AC_REFERENCE }, 56 { ENTRY(discr_value), AC_CONSTANT }, 57 { ENTRY(visibility), AC_CONSTANT }, 58 { ENTRY(import), AC_REFERENCE }, 59 { ENTRY(string_length), AC_BLOCK | AC_LOCLISTPTR }, 60 { ENTRY(common_reference), AC_REFERENCE }, 61 { ENTRY(comp_dir), AC_STRING }, 62 { ENTRY(const_value), AC_BLOCK | AC_CONSTANT | AC_STRING }, 63 { ENTRY(containing_type), AC_REFERENCE }, 64 { ENTRY(default_value), AC_REFERENCE | AC_CONSTANT | AC_FLAG }, 65 { ENTRY(inline), AC_CONSTANT }, 66 { ENTRY(is_optional), AC_FLAG }, 67 { ENTRY(lower_bound), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 68 { ENTRY(producer), AC_STRING }, 69 { ENTRY(prototyped), AC_FLAG }, 70 { ENTRY(return_addr), AC_BLOCK | AC_LOCLISTPTR }, 71 { ENTRY(start_scope), AC_CONSTANT }, 72 { ENTRY(bit_stride), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 73 { ENTRY(upper_bound), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 74 { ENTRY(abstract_origin), AC_REFERENCE }, 75 { ENTRY(accessibility), AC_CONSTANT }, 76 { ENTRY(address_class), AC_CONSTANT }, 77 { ENTRY(artificial), AC_FLAG }, 78 { ENTRY(base_types), AC_REFERENCE }, 79 { ENTRY(calling_convention), AC_CONSTANT }, 80 { ENTRY(count), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 81 { ENTRY(data_member_location), AC_BLOCK | AC_CONSTANT | AC_LOCLISTPTR }, 82 { ENTRY(decl_column), AC_CONSTANT }, 83 { ENTRY(decl_file), AC_CONSTANT }, 84 { ENTRY(decl_line), AC_CONSTANT }, 85 { ENTRY(declaration), AC_FLAG }, 86 { ENTRY(discr_list), AC_BLOCK }, 87 { ENTRY(encoding), AC_CONSTANT }, 88 { ENTRY(external), AC_FLAG }, 89 { ENTRY(frame_base), AC_BLOCK | AC_LOCLISTPTR }, 90 { ENTRY(friend), AC_REFERENCE }, 91 { ENTRY(identifier_case), AC_CONSTANT }, 92 { ENTRY(macro_info), AC_MACPTR }, 93 { ENTRY(namelist_item), AC_BLOCK | AC_REFERENCE }, 94 { ENTRY(priority), AC_REFERENCE }, 95 { ENTRY(segment), AC_BLOCK | AC_LOCLISTPTR }, 96 { ENTRY(specification), AC_REFERENCE }, 97 { ENTRY(static_link), AC_BLOCK | AC_LOCLISTPTR }, 98 { ENTRY(type), AC_REFERENCE }, 99 { ENTRY(use_location), AC_BLOCK | AC_LOCLISTPTR }, 100 { ENTRY(variable_parameter), AC_FLAG }, 101 { ENTRY(virtuality), AC_CONSTANT }, 102 { ENTRY(vtable_elem_location), AC_BLOCK | AC_LOCLISTPTR }, 103 { ENTRY(allocated), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 104 { ENTRY(associated), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 105 { ENTRY(data_location), AC_BLOCK }, 106 { ENTRY(byte_stride), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 107 { ENTRY(entry_pc), AC_ADDRESS }, 108 { ENTRY(use_UTF8), AC_FLAG }, 109 { ENTRY(extension), AC_REFERENCE }, 110 { ENTRY(ranges), AC_RANGELISTPTR }, 111 { ENTRY(trampoline), AC_ADDRESS | AC_FLAG | AC_REFERENCE 112 | AC_STRING }, 113 { ENTRY(call_column), AC_CONSTANT }, 114 { ENTRY(call_file), AC_CONSTANT }, 115 { ENTRY(call_line), AC_CONSTANT }, 116 { ENTRY(description), AC_STRING }, 117 { ENTRY(binary_scale), AC_CONSTANT }, 118 { ENTRY(decimal_scale), AC_CONSTANT }, 119 { ENTRY(small), AC_REFERENCE }, 120 { ENTRY(decimal_sign), AC_CONSTANT }, 121 { ENTRY(digit_count), AC_CONSTANT }, 122 { ENTRY(picture_string), AC_STRING }, 123 { ENTRY(mutable), AC_FLAG }, 124 { ENTRY(threads_scaled), AC_FLAG }, 125 { ENTRY(explicit), AC_FLAG }, 126 { ENTRY(object_pointer), AC_REFERENCE }, 127 { ENTRY(endianity), AC_CONSTANT }, 128 { ENTRY(elemental), AC_FLAG }, 129 { ENTRY(pure), AC_FLAG }, 130 { ENTRY(recursive), AC_FLAG }, 131 { ENTRY(signature), AC_REFERENCE }, 132 { ENTRY(main_subprogram), AC_FLAG }, 133 { ENTRY(data_bit_offset), AC_CONSTANT }, 134 { ENTRY(const_expr), AC_FLAG }, 135 { ENTRY(enum_class), AC_FLAG }, 136 { ENTRY(linkage_name), AC_STRING }, 137 { ENTRY(call_site_value), AC_BLOCK }, 138 { ENTRY(call_site_data_value), AC_BLOCK }, 139 { ENTRY(call_site_target), AC_BLOCK }, 140 { ENTRY(call_site_target_clobbered), 141 AC_BLOCK }, 142 { ENTRY(tail_call), AC_FLAG }, 143 { ENTRY(all_tail_call_sites), AC_FLAG }, 144 { ENTRY(all_call_sites), AC_FLAG }, 145 { ENTRY(all_source_call_sites), AC_FLAG }, 146 147 {} 148 }; 149 150 static const uint32 kAttributeNameInfoCount = DW_AT_linkage_name + 9; 151 static attribute_name_info_entry sAttributeNameInfos[kAttributeNameInfoCount]; 152 153 154 #undef ENTRY 155 #define ENTRY(name) "DW_FORM_" #name, DW_FORM_##name 156 157 static const attribute_info_entry kAttributeFormInfos[] = { 158 { ENTRY(addr), AC_ADDRESS }, 159 { ENTRY(block2), AC_BLOCK }, 160 { ENTRY(block4), AC_BLOCK }, 161 { ENTRY(data2), AC_CONSTANT }, 162 { ENTRY(data4), AC_CONSTANT | AC_LINEPTR | AC_LOCLISTPTR 163 | AC_MACPTR | AC_RANGELISTPTR }, 164 { ENTRY(data8), AC_CONSTANT | AC_LINEPTR | AC_LOCLISTPTR 165 | AC_MACPTR | AC_RANGELISTPTR }, 166 { ENTRY(string), AC_STRING }, 167 { ENTRY(block), AC_BLOCK }, 168 { ENTRY(block1), AC_BLOCK }, 169 { ENTRY(data1), AC_CONSTANT }, 170 { ENTRY(flag), AC_FLAG }, 171 { ENTRY(sdata), AC_CONSTANT }, 172 { ENTRY(strp), AC_STRING }, 173 { ENTRY(udata), AC_CONSTANT }, 174 { ENTRY(ref_addr), AC_REFERENCE }, 175 { ENTRY(ref1), AC_REFERENCE }, 176 { ENTRY(ref2), AC_REFERENCE }, 177 { ENTRY(ref4), AC_REFERENCE }, 178 { ENTRY(ref8), AC_REFERENCE }, 179 { ENTRY(ref_udata), AC_REFERENCE }, 180 { ENTRY(indirect), AC_REFERENCE }, 181 { ENTRY(sec_offset), AC_LINEPTR | AC_LOCLISTPTR | AC_MACPTR 182 | AC_RANGELISTPTR }, 183 { ENTRY(exprloc), AC_BLOCK }, 184 { ENTRY(flag_present), AC_FLAG }, 185 { ENTRY(ref_sig8), AC_REFERENCE }, 186 {} 187 }; 188 189 static const uint32 kAttributeFormInfoCount = DW_FORM_ref_sig8 + 1; 190 static attribute_info_entry sAttributeFormInfos[kAttributeFormInfoCount]; 191 192 static struct InitAttributeInfos { 193 InitAttributeInfos() 194 { 195 for (uint32 i = 0; kAttributeNameInfos[i].name != NULL; i++) { 196 const attribute_name_info_entry& entry = kAttributeNameInfos[i]; 197 if (entry.value <= DW_AT_linkage_name) 198 sAttributeNameInfos[entry.value] = entry; 199 else { 200 sAttributeNameInfos[DW_AT_linkage_name + 1 201 + (entry.value - DW_AT_call_site_value)] = entry; 202 } 203 } 204 205 for (uint32 i = 0; kAttributeFormInfos[i].name != NULL; i++) { 206 const attribute_info_entry& entry = kAttributeFormInfos[i]; 207 sAttributeFormInfos[entry.value] = entry; 208 } 209 } 210 } sInitAttributeInfos; 211 212 213 uint16 214 get_attribute_name_classes(uint32 name) 215 { 216 if (name <= DW_AT_linkage_name) 217 return sAttributeNameInfos[name].classes; 218 else if (name >= DW_AT_call_site_value 219 && name <= DW_AT_all_source_call_sites) { 220 return sAttributeNameInfos[DW_AT_linkage_name + 1 221 + (name - DW_AT_call_site_value)].classes; 222 } 223 224 return 0; 225 } 226 227 228 uint16 229 get_attribute_form_classes(uint32 form) 230 { 231 return form < kAttributeFormInfoCount 232 ? sAttributeFormInfos[form].classes : 0; 233 } 234 235 236 uint8 237 get_attribute_class(uint32 name, uint32 form) 238 { 239 uint16 classes = get_attribute_name_classes(name) 240 & get_attribute_form_classes(form); 241 242 int clazz = 0; 243 while (classes != 0) { 244 classes >>= 1; 245 clazz++; 246 } 247 248 return clazz; 249 } 250 251 252 const char* 253 get_attribute_name_name(uint32 name) 254 { 255 if (name <= DW_AT_linkage_name) 256 return sAttributeNameInfos[name].name; 257 else if (name >= DW_AT_call_site_value 258 && name <= DW_AT_all_source_call_sites) { 259 return sAttributeNameInfos[DW_AT_linkage_name + 1 + 260 (name - DW_AT_call_site_value)].name; 261 } 262 263 return NULL; 264 } 265 266 267 const char* 268 get_attribute_form_name(uint32 form) 269 { 270 return form < kAttributeFormInfoCount 271 ? sAttributeFormInfos[form].name : NULL; 272 } 273 274 275 DebugInfoEntrySetter 276 get_attribute_name_setter(uint32 name) 277 { 278 return (name < kAttributeNameInfoCount) 279 ? sAttributeNameInfos[name].setter : NULL; 280 } 281