00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "config.h"
00042 #include "dwarf_incl.h"
00043 #include <stdio.h>
00044 #include "dwarf_die_deliv.h"
00045
00046 int
00047 dwarf_get_address_size(Dwarf_Debug dbg,
00048 Dwarf_Half * ret_addr_size, Dwarf_Error * error)
00049 {
00050 Dwarf_Half address_size;
00051
00052 if (dbg == 0) {
00053 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
00054 return (DW_DLV_ERROR);
00055 }
00056
00057 address_size = dbg->de_pointer_size;
00058 *ret_addr_size = address_size;
00059 return DW_DLV_OK;
00060 }
00061
00062 int
00063 dwarf_dieoffset(Dwarf_Die die,
00064 Dwarf_Off * ret_offset, Dwarf_Error * error)
00065 {
00066 CHECK_DIE(die, DW_DLV_ERROR)
00067
00068 * ret_offset = (die->di_debug_info_ptr -
00069 die->di_cu_context->cc_dbg->de_debug_info);
00070 return DW_DLV_OK;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080 int
00081 dwarf_die_CU_offset(Dwarf_Die die,
00082 Dwarf_Off * cu_off, Dwarf_Error * error)
00083 {
00084 Dwarf_CU_Context cu_context;
00085
00086 CHECK_DIE(die, DW_DLV_ERROR)
00087 cu_context = die->di_cu_context;
00088
00089 *cu_off =
00090 (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info -
00091 cu_context->cc_debug_info_offset);
00092 return DW_DLV_OK;
00093 }
00094
00095
00096 int
00097 dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
00098 {
00099 CHECK_DIE(die, DW_DLV_ERROR)
00100
00101
00102 * tag = (die->di_abbrev_list->ab_tag);
00103 return DW_DLV_OK;
00104 }
00105
00106
00107 int
00108 dwarf_attrlist(Dwarf_Die die,
00109 Dwarf_Attribute ** attrbuf,
00110 Dwarf_Signed * attrcnt, Dwarf_Error * error)
00111 {
00112 Dwarf_Word attr_count = 0;
00113 Dwarf_Word i;
00114 Dwarf_Half attr;
00115 Dwarf_Half attr_form;
00116 Dwarf_Byte_Ptr abbrev_ptr;
00117 Dwarf_Abbrev_List abbrev_list;
00118 Dwarf_Attribute new_attr;
00119 Dwarf_Attribute head_attr = NULL, curr_attr;
00120 Dwarf_Attribute *attr_ptr;
00121 Dwarf_Debug dbg;
00122 Dwarf_Byte_Ptr info_ptr;
00123
00124 CHECK_DIE(die, DW_DLV_ERROR)
00125 dbg = die->di_cu_context->cc_dbg;
00126
00127 abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
00128 die->di_abbrev_list->
00129 ab_code);
00130 if (abbrev_list == NULL) {
00131 _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
00132 return (DW_DLV_ERROR);
00133 }
00134 abbrev_ptr = abbrev_list->ab_abbrev_ptr;
00135
00136 info_ptr = die->di_debug_info_ptr;
00137 SKIP_LEB128_WORD(info_ptr)
00138
00139 do {
00140 Dwarf_Unsigned utmp2;
00141
00142 DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
00143 attr = (Dwarf_Half) utmp2;
00144 DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
00145 attr_form = (Dwarf_Half) utmp2;
00146
00147 if (attr != 0) {
00148 new_attr =
00149 (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
00150 if (new_attr == NULL) {
00151 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00152 return (DW_DLV_ERROR);
00153 }
00154
00155 new_attr->ar_attribute = attr;
00156 new_attr->ar_attribute_form_direct = attr_form;
00157 new_attr->ar_attribute_form = attr_form;
00158 if(attr_form == DW_FORM_indirect) {
00159 Dwarf_Unsigned utmp6;
00160
00161 DECODE_LEB128_UWORD(info_ptr, utmp6)
00162 attr_form = (Dwarf_Half) utmp6;
00163 new_attr->ar_attribute_form = attr_form;
00164 }
00165 new_attr->ar_cu_context = die->di_cu_context;
00166 new_attr->ar_debug_info_ptr = info_ptr;
00167
00168 info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr,
00169 die->di_cu_context->
00170 cc_length_size);
00171
00172 if (head_attr == NULL)
00173 head_attr = curr_attr = new_attr;
00174 else {
00175 curr_attr->ar_next = new_attr;
00176 curr_attr = new_attr;
00177 }
00178 attr_count++;
00179 }
00180 } while (attr != 0 || attr_form != 0);
00181
00182 if (attr_count == 0) {
00183 *attrbuf = NULL;
00184 *attrcnt = 0;
00185 return (DW_DLV_NO_ENTRY);
00186 }
00187
00188 attr_ptr = (Dwarf_Attribute *)
00189 _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
00190 if (attr_ptr == NULL) {
00191 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00192 return (DW_DLV_ERROR);
00193 }
00194
00195 curr_attr = head_attr;
00196 for (i = 0; i < attr_count; i++) {
00197 *(attr_ptr + i) = curr_attr;
00198 curr_attr = curr_attr->ar_next;
00199 }
00200
00201 *attrbuf = attr_ptr;
00202 *attrcnt = attr_count;
00203 return (DW_DLV_OK);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 static Dwarf_Byte_Ptr
00218 _dwarf_get_value_ptr(Dwarf_Die die,
00219 Dwarf_Half attr, Dwarf_Half * attr_form)
00220 {
00221 Dwarf_Byte_Ptr abbrev_ptr;
00222 Dwarf_Abbrev_List abbrev_list;
00223 Dwarf_Half curr_attr;
00224 Dwarf_Half curr_attr_form;
00225 Dwarf_Byte_Ptr info_ptr;
00226
00227 abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
00228 die->di_abbrev_list->
00229 ab_code);
00230 if (abbrev_list == NULL) {
00231 *attr_form = 0;
00232 return (NULL);
00233 }
00234 abbrev_ptr = abbrev_list->ab_abbrev_ptr;
00235
00236 info_ptr = die->di_debug_info_ptr;
00237 SKIP_LEB128_WORD(info_ptr)
00238
00239 do {
00240 Dwarf_Unsigned utmp3;
00241
00242 DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
00243 curr_attr = (Dwarf_Half) utmp3;
00244 DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
00245 curr_attr_form = (Dwarf_Half) utmp3;
00246 if(curr_attr_form == DW_FORM_indirect) {
00247 Dwarf_Unsigned utmp6;
00248
00249
00250 DECODE_LEB128_UWORD(info_ptr, utmp6)
00251 curr_attr_form = (Dwarf_Half) utmp6;
00252 }
00253
00254 if (curr_attr == attr) {
00255 *attr_form = curr_attr_form;
00256 return (info_ptr);
00257 }
00258
00259 info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg,
00260 curr_attr_form, info_ptr,
00261 die->di_cu_context->
00262 cc_length_size);
00263 } while (curr_attr != 0 || curr_attr_form != 0);
00264
00265 *attr_form = 1;
00266 return (NULL);
00267 }
00268
00269
00270 int
00271 dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error)
00272 {
00273 Dwarf_Half attr_form;
00274 Dwarf_Debug dbg;
00275 Dwarf_Byte_Ptr info_ptr;
00276 Dwarf_Unsigned string_offset;
00277 int res;
00278
00279 CHECK_DIE(die, DW_DLV_ERROR)
00280
00281 info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
00282 if (info_ptr == NULL) {
00283 if (attr_form == 0) {
00284 _dwarf_error(die->di_cu_context->cc_dbg, error,
00285 DW_DLE_DIE_BAD);
00286 return (DW_DLV_ERROR);
00287 }
00288 return DW_DLV_NO_ENTRY;
00289 }
00290
00291 if (attr_form == DW_FORM_string) {
00292 *ret_name = (char *) (info_ptr);
00293 return DW_DLV_OK;
00294 }
00295
00296 dbg = die->di_cu_context->cc_dbg;
00297 if (attr_form != DW_FORM_strp) {
00298 _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
00299 return (DW_DLV_ERROR);
00300 }
00301
00302 READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned,
00303 info_ptr, die->di_cu_context->cc_length_size);
00304
00305 if (string_offset >= dbg->de_debug_str_size) {
00306 _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
00307 return (DW_DLV_ERROR);
00308 }
00309
00310 res =
00311 _dwarf_load_section(dbg,
00312 dbg->de_debug_str_index,
00313 &dbg->de_debug_str,
00314 error);
00315 if (res != DW_DLV_OK) {
00316 return res;
00317 }
00318
00319 *ret_name = (char *) (dbg->de_debug_str + string_offset);
00320 return DW_DLV_OK;
00321 }
00322
00323
00324 int
00325 dwarf_hasattr(Dwarf_Die die,
00326 Dwarf_Half attr,
00327 Dwarf_Bool * return_bool, Dwarf_Error * error)
00328 {
00329 Dwarf_Half attr_form;
00330
00331 CHECK_DIE(die, DW_DLV_ERROR)
00332
00333 if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
00334 if (attr_form == 0) {
00335 _dwarf_error(die->di_cu_context->cc_dbg, error,
00336 DW_DLE_DIE_BAD);
00337 return (DW_DLV_ERROR);
00338 }
00339 *return_bool = false;
00340 return DW_DLV_OK;
00341 }
00342
00343 *return_bool = (true);
00344 return DW_DLV_OK;
00345 }
00346
00347
00348 int
00349 dwarf_attr(Dwarf_Die die,
00350 Dwarf_Half attr,
00351 Dwarf_Attribute * ret_attr, Dwarf_Error * error)
00352 {
00353 Dwarf_Half attr_form;
00354 Dwarf_Attribute attrib;
00355 Dwarf_Byte_Ptr info_ptr;
00356 Dwarf_Debug dbg;
00357
00358 CHECK_DIE(die, DW_DLV_ERROR)
00359 dbg = die->di_cu_context->cc_dbg;
00360
00361 info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
00362 if (info_ptr == NULL) {
00363 if (attr_form == 0) {
00364 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
00365 return (DW_DLV_ERROR);
00366 }
00367 return DW_DLV_NO_ENTRY;
00368 }
00369
00370 attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
00371 if (attrib == NULL) {
00372 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00373 return (DW_DLV_ERROR);
00374 }
00375
00376 attrib->ar_attribute = attr;
00377 attrib->ar_attribute_form = attr_form;
00378 attrib->ar_attribute_form_direct = attr_form;
00379 attrib->ar_cu_context = die->di_cu_context;
00380 attrib->ar_debug_info_ptr = info_ptr;
00381 *ret_attr = (attrib);
00382 return DW_DLV_OK;
00383 }
00384
00385
00386 int
00387 dwarf_lowpc(Dwarf_Die die,
00388 Dwarf_Addr * return_addr, Dwarf_Error * error)
00389 {
00390 Dwarf_Addr ret_addr;
00391 Dwarf_Byte_Ptr info_ptr;
00392 Dwarf_Half attr_form;
00393 Dwarf_Debug dbg;
00394
00395 CHECK_DIE(die, DW_DLV_ERROR)
00396
00397 dbg = die->di_cu_context->cc_dbg;
00398 info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form);
00399 if ((info_ptr == NULL && attr_form == 0) ||
00400 (info_ptr != NULL && attr_form != DW_FORM_addr)) {
00401 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
00402 return (DW_DLV_ERROR);
00403 }
00404 if (info_ptr == NULL) {
00405 return (DW_DLV_NO_ENTRY);
00406 }
00407
00408
00409 READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
00410 info_ptr, dbg->de_pointer_size);
00411
00412 *return_addr = ret_addr;
00413 return (DW_DLV_OK);
00414 }
00415
00416
00417 int
00418 dwarf_highpc(Dwarf_Die die,
00419 Dwarf_Addr * return_addr, Dwarf_Error * error)
00420 {
00421 Dwarf_Addr ret_addr;
00422 Dwarf_Byte_Ptr info_ptr;
00423 Dwarf_Half attr_form;
00424 Dwarf_Debug dbg;
00425
00426 CHECK_DIE(die, DW_DLV_ERROR)
00427
00428 dbg = die->di_cu_context->cc_dbg;
00429 info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form);
00430 if ((info_ptr == NULL && attr_form == 0) ||
00431 (info_ptr != NULL && attr_form != DW_FORM_addr)) {
00432 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
00433 return (DW_DLV_ERROR);
00434 }
00435 if (info_ptr == NULL) {
00436 return (DW_DLV_NO_ENTRY);
00437 }
00438
00439 READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
00440 info_ptr, dbg->de_pointer_size);
00441
00442 *return_addr = ret_addr;
00443 return (DW_DLV_OK);
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 static int
00459 _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
00460 Dwarf_Half attr,
00461 Dwarf_Unsigned * return_val,
00462 Dwarf_Error * error)
00463 {
00464 Dwarf_Byte_Ptr info_ptr;
00465 Dwarf_Half attr_form;
00466 Dwarf_Unsigned ret_value;
00467 Dwarf_Debug dbg;
00468
00469 CHECK_DIE(die, DW_DLV_ERROR)
00470
00471 dbg = die->di_cu_context->cc_dbg;
00472 info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
00473 if (info_ptr != NULL) {
00474 switch (attr_form) {
00475
00476 case DW_FORM_data1:
00477 *return_val = (*(Dwarf_Small *) info_ptr);
00478 return (DW_DLV_OK);
00479
00480 case DW_FORM_data2:
00481 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
00482 info_ptr, sizeof(Dwarf_Shalf));
00483 *return_val = ret_value;
00484 return (DW_DLV_OK);
00485
00486 case DW_FORM_data4:
00487 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
00488 info_ptr, sizeof(Dwarf_sfixed));
00489 *return_val = ret_value;
00490 return (DW_DLV_OK);
00491
00492 case DW_FORM_data8:
00493 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
00494 info_ptr, sizeof(Dwarf_Unsigned));
00495 *return_val = ret_value;
00496 return (DW_DLV_OK);
00497
00498 case DW_FORM_udata:
00499 *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
00500 return (DW_DLV_OK);
00501
00502 default:
00503 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
00504 return (DW_DLV_ERROR);
00505 }
00506 }
00507 if (attr_form == 0) {
00508 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
00509 return (DW_DLV_ERROR);
00510 }
00511 return DW_DLV_NO_ENTRY;
00512 }
00513
00514
00515 int
00516 dwarf_bytesize(Dwarf_Die die,
00517 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
00518 {
00519 Dwarf_Unsigned luns;
00520 int res =
00521 _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns,
00522 error);
00523 *ret_size = luns;
00524 return res;
00525 }
00526
00527
00528 int
00529 dwarf_bitsize(Dwarf_Die die,
00530 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
00531 {
00532 Dwarf_Unsigned luns;
00533 int res;
00534
00535 res =
00536 _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns,
00537 error);
00538 *ret_size = luns;
00539 return res;
00540 }
00541
00542
00543 int
00544 dwarf_bitoffset(Dwarf_Die die,
00545 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
00546 {
00547 Dwarf_Unsigned luns;
00548 int res;
00549
00550 res =
00551 _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns,
00552 error);
00553 *ret_size = luns;
00554 return res;
00555 }
00556
00557
00558
00559 int
00560 dwarf_srclang(Dwarf_Die die,
00561 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
00562 {
00563 Dwarf_Unsigned luns;
00564 int res;
00565
00566 res =
00567 _dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns,
00568 error);
00569 *ret_size = luns;
00570 return res;
00571 }
00572
00573
00574
00575 int
00576 dwarf_arrayorder(Dwarf_Die die,
00577 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
00578 {
00579 Dwarf_Unsigned luns;
00580 int res;
00581
00582 res =
00583 _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns,
00584 error);
00585 *ret_size = luns;
00586 return res;
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596 int
00597 dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset,
00598
00599
00600
00601
00602
00603 Dwarf_Error * error)
00604 {
00605 Dwarf_Off attroff;
00606
00607 CHECK_DIE(die, DW_DLV_ERROR)
00608
00609 attroff = (attr->ar_debug_info_ptr -
00610 die->di_cu_context->cc_dbg->de_debug_info);
00611 *offset = attroff;
00612 return DW_DLV_OK;
00613 }