/* This function performs error handling as described in the libdwarf consumer document section 3. Dbg is the Dwarf_debug structure being processed. Error is a pointer to the pointer to the error descriptor that will be returned. Errval is an error code listed in dwarf_error.h. */ void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval) { Dwarf_Error errptr; /* Allow NULL dbg on entry, since sometimes that can happen and we want to report the upper-level error, not this one. */ if (error != NULL) { /* If dbg is NULL, use the alternate error struct. However, this will overwrite the earlier error. */ if (dbg != NULL) { errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); if (errptr == NULL) { fprintf(stderr, "Could not allocate Dwarf_Error structure, " "abort() in libdwarf.\n"); abort(); } } else { /* We have no dbg to work with. dwarf_init failed. We hack up a special area. */ errptr = _dwarf_special_no_dbg_error_malloc(); if (errptr == NULL) { fprintf(stderr, "Could not allocate Dwarf_Error structure, " "abort() in libdwarf..\n"); abort(); } } errptr->er_errval = errval; *error = errptr; return; } if (dbg != NULL && dbg->de_errhand != NULL) { errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); if (errptr == NULL) { fprintf(stderr, "Could not allocate Dwarf_Error structure," " abort() in libdwarf.\n"); abort(); } errptr->er_errval = errval; dbg->de_errhand(errptr, dbg->de_errarg); return; } fprintf(stderr, "abort() in libdwarf. No error argument, no handler.\n"); abort(); }
/* This function performs error handling as described in the libdwarf consumer document section 3. Dbg is the Dwarf_debug structure being processed. Error is a pointer to the pointer to the error descriptor that will be returned. Errval is an error code listed in dwarf_error.h. If the malloc arena is exhausted we return a pointer to a special static error record. This special singleton is mostly ignored by dwarf_dealloc(). Users should not be storing Dwarf_Error pointers for long so this singleton is only going to cause confusion when callers try to save an out-of-memory Dwarf_Error pointer. The _dwarf_failsafe_error is intended to be an improvement over an abort() call. The failsafe means we will not abort due to a Dwarf_Error struct creation. */ void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval) { Dwarf_Error errptr; /* Allow NULL dbg on entry, since sometimes that can happen and we want to report the upper-level error, not this one. */ if (error != NULL) { /* If dbg is NULL, use the alternate error struct. However, this will overwrite the earlier error. */ if (dbg != NULL) { errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); if (!errptr) { errptr = &_dwarf_failsafe_error; errptr->er_static_alloc = DE_STATIC; } else { errptr->er_static_alloc = DE_STANDARD; } } else { /* We have no dbg to work with. dwarf_init failed. We hack up a special area. */ errptr = _dwarf_special_no_dbg_error_malloc(); if (!errptr) { errptr = &_dwarf_failsafe_error; errptr->er_static_alloc = DE_STATIC; } else { errptr->er_static_alloc = DE_MALLOC; } } errptr->er_errval = errval; *error = errptr; return; } if (dbg != NULL && dbg->de_errhand != NULL) { errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); if (errptr == NULL) { errptr = &_dwarf_failsafe_error; errptr->er_static_alloc = DE_STATIC; } errptr->er_errval = errval; dbg->de_errhand(errptr, dbg->de_errarg); return; } fflush(stdout); fprintf(stdout, "\nNow abort() in libdwarf. " "No error argument or handler available.\n"); fflush(stdout); abort(); }
/* This function returns a pointer to a region of memory. For alloc_types that are not strings or lists of pointers, only 1 struct can be requested at a time. This is indicated by an input count of 1. For strings, count equals the length of the string it will contain, i.e it the length of the string plus 1 for the terminating null. For lists of pointers, count is equal to the number of pointers. For DW_DLA_FRAME_BLOCK, and DW_DLA_LOC_BLOCK allocation types also, count is the count of the number of structs needed. This function cannot be used to allocate a Dwarf_Debug_s struct. */ Dwarf_Ptr _dwarf_get_alloc(Dwarf_Debug dbg, Dwarf_Small alloc_type, Dwarf_Unsigned count) { Dwarf_Alloc_Hdr alloc_hdr; Dwarf_Ptr ret_mem; Dwarf_Signed size = 0; unsigned int index; unsigned int type = alloc_type; if (dbg == NULL) { return (NULL); } if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { /* internal error */ return NULL; } index = index_into_allocated[type].ia_al_num; /* zero also illegal but not tested for */ /* If the Dwarf_Debug is not fully set up, we will get index 0 for any type and must do something. 'Not fully set up' can only happen for DW_DLA_ERROR, I (davea) believe, and for that we call special code here.. */ if (index == 0) { if (alloc_type == DW_DLA_STRING) { size = count; } else if (alloc_type == DW_DLA_LIST) { size = count * sizeof(Dwarf_Ptr); } else if (alloc_type == DW_DLA_FRAME_BLOCK) { size = count * sizeof(Dwarf_Frame_Op); } else if (alloc_type == DW_DLA_LOC_BLOCK) { size = count * sizeof(Dwarf_Loc); } else if (alloc_type == DW_DLA_ADDR) { size = count * (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ? sizeof(Dwarf_Addr) : sizeof(Dwarf_Off)); } else if (alloc_type == DW_DLA_ERROR) { return _dwarf_special_no_dbg_error_malloc(); } else { /* If we get here, there is a disastrous programming error somewhere. */ #ifdef DEBUG fprintf(stderr, "libdwarf Internal error: type %d unexpected\n", (int) type); #endif } } else { alloc_hdr = &dbg->de_alloc_hdr[index]; if (alloc_hdr->ah_bytes_one_struct > 0) { #ifdef DWARF_SIMPLE_MALLOC size = alloc_hdr->ah_bytes_one_struct; #else return (_dwarf_find_memory(alloc_hdr)); #endif } else { /* Special case: should not really happen at all. */ if (type == DW_DLA_ERROR) { /* dwarf_init failure. Because dbg is incomplete we won't use it to record the malloc. */ return _dwarf_special_no_dbg_error_malloc(); } else { /* If we get here, there is a disastrous programming error somewhere. */ #ifdef DWARF_SIMPLE_MALLOC _dwarf_simple_malloc_botch(3); #endif #ifdef DEBUG fprintf(stderr, "libdwarf Internal error: Type %d unexpected\n", (int) type); #endif } } } ret_mem = malloc(size); #ifdef DWARF_SIMPLE_MALLOC _dwarf_simple_malloc_add_to_list(dbg,ret_mem,(unsigned long)size, alloc_type); #endif if (ret_mem != NULL) memset(ret_mem,0, size); return (ret_mem); }