/* Frees all memory that was not previously freed by dwarf_dealloc. Aside from certain categories. */ int dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error) { int res = DW_DLV_OK; if (dbg->de_elf_must_close) { /* Must do this *before* _dwarf_free_all_of_one_debug() as that zeroes out dbg contents */ #ifdef __SGI_FAST_LIBELF elf_sgi_free(dbg->de_elf); #else elf_end(dbg->de_elf); #endif } res = _dwarf_free_all_of_one_debug(dbg); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } dwarf_malloc_check_complete("After Final free"); return res; }
/* A finish routine that is completely unaware of ELF. Frees all memory that was not previously freed by dwarf_dealloc. Aside frmo certain categories. */ int dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error * error) { int res = _dwarf_free_all_of_one_debug(dbg); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } return res; }
/* Use a Dwarf_Obj_Access_Interface to kick things off. All other init routines eventually use this one. The returned Dwarf_Debug contains a copy of *obj the callers copy of *obj may be freed whenever the caller wishes. */ int dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* ret_dbg, Dwarf_Error* error) { Dwarf_Debug dbg = 0; int setup_result = DW_DLV_OK; dbg = _dwarf_get_debug(); if (dbg == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } dbg->de_errhand = errhand; dbg->de_errarg = errarg; dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; #ifdef HAVE_OLD_FRAME_CFA_COL /* DW_FRAME_CFA_COL is really only suitable for old libdwarf frame interfaces and its value of 0 there is only usable where (as in MIPS) register 0 has no value other than 0 so we can use the frame table column 0 for the CFA value (and rely on client software to know when 'register 0' is the cfa and when to just use a value 0 for register 0). */ dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL; #else dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL3; #endif dbg->de_frame_same_value_number = DW_FRAME_SAME_VAL; dbg->de_frame_undefined_value_number = DW_FRAME_UNDEFINED_VAL; dbg->de_obj_file = obj; setup_result = _dwarf_setup(dbg, error); if (setup_result != DW_DLV_OK) { /* The status we want to return here is of _dwarf_setup, not of the _dwarf_free_all_of_one_debug(dbg) call. So use a local status variable for the free. */ int freeresult = _dwarf_free_all_of_one_debug(dbg); if (freeresult == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } dwarf_malloc_check_complete("After Final free"); return setup_result; } dwarf_harmless_init(&dbg->de_harmless_errors, DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE); /* This call cannot fail: allocates nothing, releases nothing */ _dwarf_setup_debug(dbg); *ret_dbg = dbg; return DW_DLV_OK; }
/* A finish routine that is completely unaware of ELF. Frees all memory that was not previously freed by dwarf_dealloc. Aside frmo certain categories. */ int dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error * error) { int res = DW_DLV_OK; res = _dwarf_free_all_of_one_debug(dbg); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } dwarf_malloc_check_complete("After Final free"); return res; }
/* Use a Dwarf_Obj_Access_Interface to kick things off. All other init routines eventually use this one. The returned Dwarf_Debug contains a copy of *obj the callers copy of *obj may be freed whenever the caller wishes. */ int dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* ret_dbg, Dwarf_Error* error) { Dwarf_Debug dbg = 0; int setup_result = DW_DLV_OK; dbg = _dwarf_get_debug(); if (dbg == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } dbg->de_errhand = errhand; dbg->de_errarg = errarg; dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; #ifdef HAVE_OLD_FRAME_CFA_COL /* DW_FRAME_CFA_COL is really only suitable for old libdwarf frame interfaces and its value of 0 there is only usable where (as in MIPS) register 0 has no value other than 0 so we can use the frame table column 0 for the CFA value (and rely on client software to know when 'register 0' is the cfa and when to just use a value 0 for register 0). */ dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL; #else dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL3; #endif dbg->de_frame_same_value_number = DW_FRAME_SAME_VAL; dbg->de_frame_undefined_value_number = DW_FRAME_UNDEFINED_VAL; dbg->de_obj_file = obj; setup_result = _dwarf_setup(dbg, error); if (setup_result == DW_DLV_OK) { int fission_result = load_debugfission_tables(dbg,error); /* In most cases we get setup_result == DW_DLV_NO_ENTRY here as having debugfission (.dwp objects) is fairly rare. */ if (fission_result == DW_DLV_ERROR) { /* Something is very wrong. */ setup_result = fission_result; } } if (setup_result != DW_DLV_OK) { int freeresult = 0; /* We cannot use any _dwarf_setup() error here as we are freeing dbg, making that error (setup as part of dbg) stale. Hence we have to make a new error without a dbg. But error might be NULL and the init call error-handler function might be set. */ int myerr = 0; if ( (setup_result == DW_DLV_ERROR) && error ) { /* Preserve our _dwarf_setup error number, but this does not apply if error NULL. */ myerr = dwarf_errno(*error); /* deallocate the soon-stale error pointer. */ dwarf_dealloc(dbg,*error,DW_DLA_ERROR); *error = 0; } /* The status we want to return here is of _dwarf_setup, not of the _dwarf_free_all_of_one_debug(dbg) call. So use a local status variable for the free. */ freeresult = _dwarf_free_all_of_one_debug(dbg); dbg = 0; /* DW_DLV_NO_ENTRY not possible in freeresult */ if (freeresult == DW_DLV_ERROR) { /* Use the _dwarf_setup error number. If error is NULL the following will issue a message on stderr and abort(), as without dbg there is no error-handler function. */ _dwarf_error(NULL,error,DW_DLE_DBG_ALLOC); return DW_DLV_ERROR; } if (setup_result == DW_DLV_ERROR) { /* Use the _dwarf_setup error number. If error is NULL the following will issue a message on stderr and abort(), as without dbg there is no error-handler function. */ _dwarf_error(NULL,error,myerr); } return setup_result; } dwarf_harmless_init(&dbg->de_harmless_errors, DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE); *ret_dbg = dbg; return DW_DLV_OK; }