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
00042 #include "config.h"
00043 #include "dwarf_incl.h"
00044 #include <stdio.h>
00045 #include "dwarf_global.h"
00046
00047 int
00048 dwarf_get_globals(Dwarf_Debug dbg,
00049 Dwarf_Global ** globals,
00050 Dwarf_Signed * return_count, Dwarf_Error * error)
00051 {
00052 int res;
00053
00054 res =
00055 _dwarf_load_section(dbg,
00056 dbg->de_debug_pubnames_index,
00057 &dbg->de_debug_pubnames,
00058 error);
00059 if (res != DW_DLV_OK) {
00060 return res;
00061 }
00062
00063
00064
00065 return _dwarf_internal_get_pubnames_like_data(dbg,
00066 dbg->
00067 de_debug_pubnames,
00068 dbg->
00069 de_debug_pubnames_size,
00070 globals, return_count,
00071 error,
00072 DW_DLA_GLOBAL_CONTEXT,
00073 DW_DLE_PUBNAMES_LENGTH_BAD,
00074 DW_DLE_PUBNAMES_VERSION_ERROR);
00075
00076 }
00077
00078
00079
00080
00081 int
00082 _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,
00083 Dwarf_Small * section_data_ptr,
00084 Dwarf_Unsigned section_length,
00085 Dwarf_Global ** globals,
00086 Dwarf_Signed * return_count,
00087 Dwarf_Error * error,
00088 int allocation_code,
00089 int length_err_num,
00090 int version_err_num)
00091 {
00092
00093
00094 Dwarf_Small *pubnames_like_ptr;
00095
00096
00097
00098
00099
00100
00101
00102 Dwarf_Global_Context pubnames_context;
00103
00104 Dwarf_Half version;
00105
00106
00107
00108
00109 Dwarf_Off die_offset_in_cu;
00110
00111 Dwarf_Unsigned global_count = 0;
00112
00113
00114 Dwarf_Global global;
00115
00116
00117
00118
00119 Dwarf_Chain curr_chain, prev_chain, head_chain = NULL;
00120
00121
00122 Dwarf_Global *ret_globals;
00123
00124
00125 Dwarf_Unsigned i;
00126
00127
00128
00129
00130 if (dbg == NULL) {
00131 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
00132 return (DW_DLV_ERROR);
00133 }
00134
00135 if(!dbg->de_debug_info) {
00136 int res = _dwarf_load_debug_info(dbg,error);
00137 if(res != DW_DLV_OK) {
00138 return res;
00139 }
00140 }
00141
00142 if (section_data_ptr == NULL) {
00143 return (DW_DLV_NO_ENTRY);
00144 }
00145
00146 pubnames_like_ptr = section_data_ptr;
00147 do {
00148 Dwarf_Unsigned length;
00149 int local_extension_size;
00150 int local_length_size;
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 Dwarf_Small *pubnames_ptr_past_end_cu = 0;
00161
00162
00163 pubnames_context = (Dwarf_Global_Context)
00164 _dwarf_get_alloc(dbg, allocation_code, 1);
00165 if (pubnames_context == NULL) {
00166 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00167 return (DW_DLV_ERROR);
00168 }
00169
00170
00171 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
00172 pubnames_like_ptr, local_length_size,
00173 local_extension_size);
00174 pubnames_context->pu_length_size = local_length_size;
00175 pubnames_context->pu_extension_size = local_extension_size;
00176 pubnames_context->pu_dbg = dbg;
00177
00178 pubnames_ptr_past_end_cu = pubnames_like_ptr + length;
00179
00180 READ_UNALIGNED(dbg, version, Dwarf_Half,
00181 pubnames_like_ptr, sizeof(Dwarf_Half));
00182 pubnames_like_ptr += sizeof(Dwarf_Half);
00183 if (version != CURRENT_VERSION_STAMP) {
00184 _dwarf_error(dbg, error, version_err_num);
00185 return (DW_DLV_ERROR);
00186 }
00187
00188
00189 READ_UNALIGNED(dbg, pubnames_context->pu_offset_of_cu_header,
00190 Dwarf_Off, pubnames_like_ptr,
00191 pubnames_context->pu_length_size);
00192 pubnames_like_ptr += pubnames_context->pu_length_size;
00193
00194
00195 READ_UNALIGNED(dbg, pubnames_context->pu_info_length,
00196 Dwarf_Unsigned, pubnames_like_ptr,
00197 pubnames_context->pu_length_size);
00198 pubnames_like_ptr += pubnames_context->pu_length_size;
00199
00200 if (pubnames_like_ptr > (section_data_ptr + section_length)) {
00201 _dwarf_error(dbg, error, length_err_num);
00202 return (DW_DLV_ERROR);
00203 }
00204
00205
00206
00207 READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
00208 pubnames_like_ptr,
00209 pubnames_context->pu_length_size);
00210 pubnames_like_ptr += pubnames_context->pu_length_size;
00211
00212
00213 while (die_offset_in_cu != 0) {
00214
00215
00216
00217 global =
00218 (Dwarf_Global) _dwarf_get_alloc(dbg, DW_DLA_GLOBAL, 1);
00219 if (global == NULL) {
00220 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00221 return (DW_DLV_ERROR);
00222 }
00223 global_count++;
00224
00225 global->gl_context = pubnames_context;
00226
00227 global->gl_named_die_offset_within_cu = die_offset_in_cu;
00228
00229 global->gl_name = pubnames_like_ptr;
00230
00231 pubnames_like_ptr = pubnames_like_ptr +
00232 strlen((char *) pubnames_like_ptr) + 1;
00233
00234
00235
00236 curr_chain =
00237 (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
00238 if (curr_chain == NULL) {
00239 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00240 return (DW_DLV_ERROR);
00241 }
00242
00243
00244 curr_chain->ch_item = (Dwarf_Global) global;
00245
00246 if (head_chain == NULL)
00247 head_chain = prev_chain = curr_chain;
00248 else {
00249 prev_chain->ch_next = curr_chain;
00250 prev_chain = curr_chain;
00251 }
00252
00253
00254 READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
00255 pubnames_like_ptr,
00256 pubnames_context->pu_length_size);
00257
00258 pubnames_like_ptr += pubnames_context->pu_length_size;
00259 if (pubnames_like_ptr > (section_data_ptr + section_length)) {
00260 _dwarf_error(dbg, error, length_err_num);
00261 return (DW_DLV_ERROR);
00262 }
00263 }
00264
00265 if(pubnames_like_ptr > pubnames_ptr_past_end_cu) {
00266
00267
00268
00269 _dwarf_error(dbg, error, length_err_num);
00270 return (DW_DLV_ERROR);
00271
00272 }
00273
00274
00275
00276
00277
00278
00279 pubnames_like_ptr = pubnames_ptr_past_end_cu;
00280
00281 } while (pubnames_like_ptr < (section_data_ptr + section_length));
00282
00283
00284 ret_globals = (Dwarf_Global *)
00285 _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
00286 if (ret_globals == NULL) {
00287 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00288 return (DW_DLV_ERROR);
00289 }
00290
00291
00292
00293
00294 curr_chain = head_chain;
00295 for (i = 0; i < global_count; i++) {
00296 *(ret_globals + i) = curr_chain->ch_item;
00297 prev_chain = curr_chain;
00298 curr_chain = curr_chain->ch_next;
00299 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
00300 }
00301
00302 *globals = ret_globals;
00303 *return_count = (global_count);
00304 return DW_DLV_OK;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313 int
00314 dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error)
00315 {
00316 if (glob == NULL) {
00317 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
00318 return (DW_DLV_ERROR);
00319 }
00320
00321 *ret_name = (char *) (glob->gl_name);
00322 return DW_DLV_OK;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 int
00334 dwarf_global_die_offset(Dwarf_Global global,
00335 Dwarf_Off * ret_off, Dwarf_Error * error)
00336 {
00337 if (global == NULL) {
00338 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
00339 return (DW_DLV_ERROR);
00340 }
00341
00342 if (global->gl_context == NULL) {
00343 _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
00344 return (DW_DLV_ERROR);
00345 }
00346
00347 *ret_off = (global->gl_named_die_offset_within_cu +
00348 global->gl_context->pu_offset_of_cu_header);
00349 return DW_DLV_OK;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 int
00367 dwarf_global_cu_offset(Dwarf_Global global,
00368 Dwarf_Off * cu_header_offset,
00369 Dwarf_Error * error)
00370 {
00371 Dwarf_Global_Context con;
00372
00373 if (global == NULL) {
00374 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
00375 return (DW_DLV_ERROR);
00376 }
00377
00378 con = global->gl_context;
00379
00380 if (con == NULL) {
00381 _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
00382 return (DW_DLV_ERROR);
00383 }
00384
00385
00386
00387 *cu_header_offset = con->pu_offset_of_cu_header;
00388
00389 return DW_DLV_OK;
00390 }
00391
00392
00393
00394
00395
00396 int
00397 dwarf_global_name_offsets(Dwarf_Global global,
00398 char **ret_name,
00399 Dwarf_Off * die_offset,
00400 Dwarf_Off * cu_die_offset,
00401 Dwarf_Error * error)
00402 {
00403 Dwarf_Global_Context con;
00404 Dwarf_Debug dbg;
00405 Dwarf_Off off;
00406
00407 if (global == NULL) {
00408 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
00409 return (DW_DLV_ERROR);
00410 }
00411
00412 con = global->gl_context;
00413
00414 if (con == NULL) {
00415 _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
00416 return (DW_DLV_ERROR);
00417 }
00418
00419 off = con->pu_offset_of_cu_header;
00420 if (die_offset != NULL) {
00421 *die_offset = global->gl_named_die_offset_within_cu + off;
00422 }
00423
00424 dbg = con->pu_dbg;
00425 if (dbg == NULL) {
00426 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
00427 return (DW_DLV_ERROR);
00428 }
00429
00430 if (cu_die_offset != NULL) {
00431 int res = _dwarf_load_debug_info(dbg,error);
00432 if(res != DW_DLV_OK) {
00433 return res;
00434 }
00435 *cu_die_offset = off + _dwarf_length_of_cu_header(dbg, off);
00436 }
00437
00438 *ret_name = (char *) global->gl_name;
00439
00440 return DW_DLV_OK;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 int
00454 dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
00455 Dwarf_Off
00456 in_cu_header_offset,
00457 Dwarf_Off *
00458 out_cu_die_offset,
00459 Dwarf_Error * err)
00460 {
00461 Dwarf_Off len =
00462 _dwarf_length_of_cu_header(dbg, in_cu_header_offset);
00463
00464 Dwarf_Off newoff = in_cu_header_offset + len;
00465
00466 *out_cu_die_offset = newoff;
00467 return DW_DLV_OK;
00468 }