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_ADDRPTR = 1 << (ATTRIBUTE_CLASS_ADDRPTR - 1), 14 AC_BLOCK = 1 << (ATTRIBUTE_CLASS_BLOCK - 1), 15 AC_CONSTANT = 1 << (ATTRIBUTE_CLASS_CONSTANT - 1), 16 AC_FLAG = 1 << (ATTRIBUTE_CLASS_FLAG - 1), 17 AC_LINEPTR = 1 << (ATTRIBUTE_CLASS_LINEPTR - 1), 18 AC_LOCLIST = 1 << (ATTRIBUTE_CLASS_LOCLIST - 1), 19 AC_LOCLISTPTR = 1 << (ATTRIBUTE_CLASS_LOCLISTPTR - 1), 20 AC_MACPTR = 1 << (ATTRIBUTE_CLASS_MACPTR - 1), 21 AC_RANGELIST = 1 << (ATTRIBUTE_CLASS_RANGELIST - 1), 22 AC_RANGELISTPTR = 1 << (ATTRIBUTE_CLASS_RANGELISTPTR - 1), 23 AC_REFERENCE = 1 << (ATTRIBUTE_CLASS_REFERENCE - 1), 24 AC_STRING = 1 << (ATTRIBUTE_CLASS_STRING - 1), 25 AC_STROFFSETSPTR= 1 << (ATTRIBUTE_CLASS_STROFFSETSPTR - 1), 26 }; 27 28 29 struct attribute_info_entry { 30 const char* name; 31 uint16 value; 32 uint16 classes; 33 }; 34 35 struct attribute_name_info_entry { 36 const char* name; 37 DebugInfoEntrySetter setter; 38 uint16 value; 39 uint16 classes; 40 }; 41 42 43 #undef ENTRY 44 #define ENTRY(name) "DW_AT_" #name, &DebugInfoEntry::AddAttribute_##name, \ 45 DW_AT_##name 46 47 static const attribute_name_info_entry kAttributeNameInfos[] = { 48 { ENTRY(sibling), AC_REFERENCE }, 49 { ENTRY(location), AC_BLOCK | AC_LOCLIST }, 50 { ENTRY(name), AC_STRING }, 51 { ENTRY(ordering), AC_CONSTANT }, 52 { ENTRY(byte_size), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 53 { ENTRY(bit_offset), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 54 { ENTRY(bit_size), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 55 { ENTRY(stmt_list), AC_LINEPTR }, 56 { ENTRY(low_pc), AC_ADDRESS | AC_CONSTANT | AC_REFERENCE }, 57 { ENTRY(high_pc), AC_ADDRESS | AC_CONSTANT | AC_REFERENCE }, 58 { ENTRY(language), AC_CONSTANT }, 59 { ENTRY(discr), AC_REFERENCE }, 60 { ENTRY(discr_value), AC_CONSTANT }, 61 { ENTRY(visibility), AC_CONSTANT }, 62 { ENTRY(import), AC_REFERENCE }, 63 { ENTRY(string_length), AC_BLOCK | AC_LOCLIST }, 64 { ENTRY(common_reference), AC_REFERENCE }, 65 { ENTRY(comp_dir), AC_STRING }, 66 { ENTRY(const_value), AC_BLOCK | AC_CONSTANT | AC_STRING }, 67 { ENTRY(containing_type), AC_REFERENCE }, 68 { ENTRY(default_value), AC_REFERENCE | AC_CONSTANT | AC_FLAG }, 69 { ENTRY(inline), AC_CONSTANT }, 70 { ENTRY(is_optional), AC_FLAG }, 71 { ENTRY(lower_bound), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 72 { ENTRY(producer), AC_STRING }, 73 { ENTRY(prototyped), AC_FLAG }, 74 { ENTRY(return_addr), AC_BLOCK | AC_LOCLIST }, 75 { ENTRY(start_scope), AC_CONSTANT }, 76 { ENTRY(bit_stride), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 77 { ENTRY(upper_bound), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 78 { ENTRY(abstract_origin), AC_REFERENCE }, 79 { ENTRY(accessibility), AC_CONSTANT }, 80 { ENTRY(address_class), AC_CONSTANT }, 81 { ENTRY(artificial), AC_FLAG }, 82 { ENTRY(base_types), AC_REFERENCE }, 83 { ENTRY(calling_convention), AC_CONSTANT }, 84 { ENTRY(count), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 85 { ENTRY(data_member_location), AC_BLOCK | AC_CONSTANT | AC_LOCLIST }, 86 { ENTRY(decl_column), AC_CONSTANT }, 87 { ENTRY(decl_file), AC_CONSTANT }, 88 { ENTRY(decl_line), AC_CONSTANT }, 89 { ENTRY(declaration), AC_FLAG }, 90 { ENTRY(discr_list), AC_BLOCK }, 91 { ENTRY(encoding), AC_CONSTANT }, 92 { ENTRY(external), AC_FLAG }, 93 { ENTRY(frame_base), AC_BLOCK | AC_LOCLIST }, 94 { ENTRY(friend), AC_REFERENCE }, 95 { ENTRY(identifier_case), AC_CONSTANT }, 96 { ENTRY(macro_info), AC_MACPTR }, 97 { ENTRY(namelist_item), AC_BLOCK | AC_REFERENCE }, 98 { ENTRY(priority), AC_REFERENCE }, 99 { ENTRY(segment), AC_BLOCK | AC_LOCLIST }, 100 { ENTRY(specification), AC_REFERENCE }, 101 { ENTRY(static_link), AC_BLOCK | AC_LOCLIST }, 102 { ENTRY(type), AC_REFERENCE }, 103 { ENTRY(use_location), AC_BLOCK | AC_LOCLIST }, 104 { ENTRY(variable_parameter), AC_FLAG }, 105 { ENTRY(virtuality), AC_CONSTANT }, 106 { ENTRY(vtable_elem_location), AC_BLOCK | AC_LOCLIST }, 107 { ENTRY(allocated), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 108 { ENTRY(associated), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 109 { ENTRY(data_location), AC_BLOCK }, 110 { ENTRY(byte_stride), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, 111 { ENTRY(entry_pc), AC_ADDRESS }, 112 { ENTRY(use_UTF8), AC_FLAG }, 113 { ENTRY(extension), AC_REFERENCE }, 114 { ENTRY(ranges), AC_RANGELIST }, 115 { ENTRY(trampoline), AC_ADDRESS | AC_FLAG | AC_REFERENCE 116 | AC_STRING }, 117 { ENTRY(call_column), AC_CONSTANT }, 118 { ENTRY(call_file), AC_CONSTANT }, 119 { ENTRY(call_line), AC_CONSTANT }, 120 { ENTRY(description), AC_STRING }, 121 { ENTRY(binary_scale), AC_CONSTANT }, 122 { ENTRY(decimal_scale), AC_CONSTANT }, 123 { ENTRY(small), AC_REFERENCE }, 124 { ENTRY(decimal_sign), AC_CONSTANT }, 125 { ENTRY(digit_count), AC_CONSTANT }, 126 { ENTRY(picture_string), AC_STRING }, 127 { ENTRY(mutable), AC_FLAG }, 128 { ENTRY(threads_scaled), AC_FLAG }, 129 { ENTRY(explicit), AC_FLAG }, 130 { ENTRY(object_pointer), AC_REFERENCE }, 131 { ENTRY(endianity), AC_CONSTANT }, 132 { ENTRY(elemental), AC_FLAG }, 133 { ENTRY(pure), AC_FLAG }, 134 { ENTRY(recursive), AC_FLAG }, 135 { ENTRY(signature), AC_REFERENCE }, 136 { ENTRY(main_subprogram), AC_FLAG }, 137 { ENTRY(data_bit_offset), AC_CONSTANT }, 138 { ENTRY(const_expr), AC_FLAG }, 139 { ENTRY(enum_class), AC_FLAG }, 140 { ENTRY(linkage_name), AC_STRING }, 141 { ENTRY(string_length_bit_size), 142 AC_CONSTANT }, 143 { ENTRY(string_length_byte_size), 144 AC_CONSTANT }, 145 { ENTRY(rank), AC_CONSTANT | AC_BLOCK }, 146 { ENTRY(str_offsets_base), AC_STROFFSETSPTR }, 147 { ENTRY(addr_base), AC_ADDRPTR }, 148 { ENTRY(rnglists_base), AC_RANGELISTPTR }, 149 { ENTRY(dwo_name), AC_STRING }, 150 { ENTRY(reference), AC_FLAG }, 151 { ENTRY(rvalue_reference), AC_FLAG }, 152 { ENTRY(macros), AC_MACPTR }, 153 { ENTRY(call_all_calls), AC_FLAG }, 154 { ENTRY(call_all_source_calls), AC_FLAG }, 155 { ENTRY(call_all_tail_calls), AC_FLAG }, 156 { ENTRY(call_return_pc), AC_ADDRESS }, 157 { ENTRY(call_value), AC_BLOCK }, 158 { ENTRY(call_origin), AC_BLOCK }, 159 { ENTRY(call_parameter), AC_REFERENCE }, 160 { ENTRY(call_pc), AC_ADDRESS }, 161 { ENTRY(call_tail_call), AC_FLAG }, 162 { ENTRY(call_target), AC_BLOCK }, 163 { ENTRY(call_target_clobbered), AC_BLOCK }, 164 { ENTRY(call_data_location), AC_BLOCK }, 165 { ENTRY(call_data_value), AC_BLOCK }, 166 { ENTRY(noreturn), AC_FLAG }, 167 { ENTRY(alignment), AC_CONSTANT }, 168 { ENTRY(export_symbols), AC_FLAG }, 169 { ENTRY(deleted), AC_FLAG }, 170 { ENTRY(defaulted), AC_CONSTANT }, 171 { ENTRY(loclists_base), AC_LOCLISTPTR }, 172 { ENTRY(call_site_value), AC_BLOCK }, 173 { ENTRY(call_site_data_value), AC_BLOCK }, 174 { ENTRY(call_site_target), AC_BLOCK }, 175 { ENTRY(call_site_target_clobbered), 176 AC_BLOCK }, 177 { ENTRY(tail_call), AC_FLAG }, 178 { ENTRY(all_tail_call_sites), AC_FLAG }, 179 { ENTRY(all_call_sites), AC_FLAG }, 180 { ENTRY(all_source_call_sites), AC_FLAG }, 181 182 {} 183 }; 184 185 static const uint32 kAttributeNameInfoCount = DW_AT_loclists_base + 9; 186 static attribute_name_info_entry sAttributeNameInfos[kAttributeNameInfoCount]; 187 188 189 #undef ENTRY 190 #define ENTRY(name) "DW_FORM_" #name, DW_FORM_##name 191 192 static const attribute_info_entry kAttributeFormInfos[] = { 193 { ENTRY(addr), AC_ADDRESS }, 194 { ENTRY(block2), AC_BLOCK }, 195 { ENTRY(block4), AC_BLOCK }, 196 { ENTRY(data2), AC_CONSTANT }, 197 { ENTRY(data4), AC_CONSTANT | AC_LINEPTR | AC_LOCLIST 198 | AC_MACPTR | AC_RANGELIST }, 199 { ENTRY(data8), AC_CONSTANT | AC_LINEPTR | AC_LOCLIST 200 | AC_MACPTR | AC_RANGELIST }, 201 { ENTRY(string), AC_STRING }, 202 { ENTRY(block), AC_BLOCK }, 203 { ENTRY(block1), AC_BLOCK }, 204 { ENTRY(data1), AC_CONSTANT }, 205 { ENTRY(flag), AC_FLAG }, 206 { ENTRY(sdata), AC_CONSTANT }, 207 { ENTRY(strp), AC_STRING }, 208 { ENTRY(udata), AC_CONSTANT }, 209 { ENTRY(ref_addr), AC_REFERENCE }, 210 { ENTRY(ref1), AC_REFERENCE }, 211 { ENTRY(ref2), AC_REFERENCE }, 212 { ENTRY(ref4), AC_REFERENCE }, 213 { ENTRY(ref8), AC_REFERENCE }, 214 { ENTRY(ref_udata), AC_REFERENCE }, 215 { ENTRY(indirect), AC_REFERENCE }, 216 { ENTRY(sec_offset), AC_ADDRPTR | AC_LINEPTR 217 | AC_LOCLIST | AC_LOCLISTPTR 218 | AC_MACPTR 219 | AC_RANGELIST | AC_RANGELISTPTR 220 | AC_STROFFSETSPTR }, 221 { ENTRY(exprloc), AC_BLOCK }, 222 { ENTRY(flag_present), AC_FLAG }, 223 { ENTRY(strx), AC_STRING }, 224 { ENTRY(addrx), AC_ADDRESS }, 225 { ENTRY(ref_sup4), AC_REFERENCE }, 226 { ENTRY(strp_sup), AC_STRING }, 227 { ENTRY(data16), AC_CONSTANT }, 228 { ENTRY(line_strp), AC_STRING }, 229 { ENTRY(ref_sig8), AC_REFERENCE }, 230 { ENTRY(implicit_const), 231 AC_CONSTANT }, 232 { ENTRY(loclistx), AC_LOCLIST }, 233 { ENTRY(rnglistx), AC_RANGELIST }, 234 { ENTRY(ref_sup8), AC_REFERENCE }, 235 { ENTRY(strx1), AC_STRING }, 236 { ENTRY(strx2), AC_STRING }, 237 { ENTRY(strx3), AC_STRING }, 238 { ENTRY(strx4), AC_STRING }, 239 { ENTRY(addrx1), AC_ADDRESS }, 240 { ENTRY(addrx2), AC_ADDRESS }, 241 { ENTRY(addrx3), AC_ADDRESS }, 242 { ENTRY(addrx4), AC_ADDRESS }, 243 {} 244 }; 245 246 static const uint32 kAttributeFormInfoCount = DW_FORM_addrx4 + 1; 247 static attribute_info_entry sAttributeFormInfos[kAttributeFormInfoCount]; 248 249 static struct InitAttributeInfos { 250 InitAttributeInfos() 251 { 252 for (uint32 i = 0; kAttributeNameInfos[i].name != NULL; i++) { 253 const attribute_name_info_entry& entry = kAttributeNameInfos[i]; 254 if (entry.value <= DW_AT_loclists_base) 255 sAttributeNameInfos[entry.value] = entry; 256 else { 257 sAttributeNameInfos[DW_AT_loclists_base + 1 258 + (entry.value - DW_AT_call_site_value)] = entry; 259 } 260 } 261 262 for (uint32 i = 0; kAttributeFormInfos[i].name != NULL; i++) { 263 const attribute_info_entry& entry = kAttributeFormInfos[i]; 264 sAttributeFormInfos[entry.value] = entry; 265 } 266 } 267 } sInitAttributeInfos; 268 269 270 uint16 271 get_attribute_name_classes(uint32 name) 272 { 273 if (name <= DW_AT_loclists_base) 274 return sAttributeNameInfos[name].classes; 275 else if (name >= DW_AT_call_site_value 276 && name <= DW_AT_all_source_call_sites) { 277 return sAttributeNameInfos[DW_AT_loclists_base + 1 278 + (name - DW_AT_call_site_value)].classes; 279 } 280 281 return 0; 282 } 283 284 285 uint16 286 get_attribute_form_classes(uint32 form) 287 { 288 return form < kAttributeFormInfoCount 289 ? sAttributeFormInfos[form].classes : 0; 290 } 291 292 293 uint8 294 get_attribute_class(uint32 name, uint32 form) 295 { 296 uint16 classes = get_attribute_name_classes(name) 297 & get_attribute_form_classes(form); 298 299 int clazz = 0; 300 while (classes != 0) { 301 classes >>= 1; 302 clazz++; 303 } 304 305 return clazz; 306 } 307 308 309 const char* 310 get_attribute_name_name(uint32 name) 311 { 312 if (name <= DW_AT_loclists_base) 313 return sAttributeNameInfos[name].name; 314 else if (name >= DW_AT_call_site_value 315 && name <= DW_AT_all_source_call_sites) { 316 return sAttributeNameInfos[DW_AT_loclists_base + 1 + 317 (name - DW_AT_call_site_value)].name; 318 } 319 320 return NULL; 321 } 322 323 324 const char* 325 get_attribute_form_name(uint32 form) 326 { 327 return form < kAttributeFormInfoCount 328 ? sAttributeFormInfos[form].name : NULL; 329 } 330 331 332 DebugInfoEntrySetter 333 get_attribute_name_setter(uint32 name) 334 { 335 return (name < kAttributeNameInfoCount) 336 ? sAttributeNameInfos[name].setter : NULL; 337 } 338