예제 #1
0
/* 
    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();
}
예제 #2
0
/*  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();
}
예제 #3
0
/*
    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);
}