07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Copyright (C) 2010 David Anderson. All Rights Reserved.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This program is free software; you can redistribute it and/or modify it
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe under the terms of version 2.1 of the GNU Lesser General Public License
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe as published by the Free Software Foundation.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This program is distributed in the hope that it would be useful, but
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Further, this software is distributed without any warranty that it is
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free of the rightful claim of any third person regarding infringement
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe or the like. Any license provided herein, whether implied or
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe otherwise, applies only to this software file. Patent licenses, if
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe any, provided herein do not apply to combinations of this program with
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe other software, or any other product whatsoever.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe You should have received a copy of the GNU Lesser General Public
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe License along with this program; if not, write the Free Software
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe USA.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This implements _dwarf_insert_harmless_error
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe and related helper functions for recording
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe compiler errors that need not make the input
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unusable.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Applications can use dwarf_get_harmless_error_list to
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe find (and possibly print) a warning about such errors.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe The initial error reported here is
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE which was a
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe bug in a specific compiler.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe It is a fixed length circular list to constrain
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe the space used for errors.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe The assumption is that these errors are exceedingly
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe rare, and indicate a broken compiler (the one that
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe produced the object getting the error(s)).
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dh_maxcount is recorded internally as 1 greater than
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe requested. Hiding the fact we always leave one
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe slot unused (at least). So a user request for
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe N slots really gives the user N usable slots.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "config.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "dwarf_incl.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <stdio.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <stdlib.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "dwarf_frame.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "dwarf_harmless.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/* The pointers returned here through errmsg_ptrs_array
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe become invalidated by any call to libdwarf. Any call.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweint dwarf_get_harmless_error_list(Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned count,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe const char ** errmsg_ptrs_array,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned * errs_count)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!dhp->dh_errors) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errs_count = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_NO_ENTRY;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(dhp->dh_errs_count == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_NO_ENTRY;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(errs_count) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *errs_count = dhp->dh_errs_count;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(count) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* NULL terminate the array of pointers */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe --count;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe errmsg_ptrs_array[count] = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(dhp->dh_next_to_use != dhp->dh_first) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned i = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned cur = dhp->dh_first;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe for(i = 0; cur != dhp->dh_next_to_use; ++i) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(i >= count ) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* All output spaces are used. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe errmsg_ptrs_array[i] = dhp->dh_errors[cur];
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe cur = (cur +1) % dhp->dh_maxcount;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe errmsg_ptrs_array[i] = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_next_to_use = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_first = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errs_count = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return DW_DLV_OK;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/* strncpy does not null-terminate, this does it. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowestatic void
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowesafe_strncpy(char *targ, char *src, unsigned spaceavail)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned goodcount = spaceavail-1;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(spaceavail < 1) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return; /* impossible */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe strncpy(targ,src,goodcount);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe targ[goodcount] = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/* Insertion made public is only for testing the harmless error code,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe it is not necessarily useful for libdwarf client code aside
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe from code testing libdwarf. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowevoid dwarf_insert_harmless_error(Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe char *newerror)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned next = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned cur = dhp->dh_next_to_use;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe char *msgspace;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!dhp->dh_errors) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errs_count++;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe msgspace = dhp->dh_errors[cur];
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe safe_strncpy(msgspace, newerror,DW_HARMLESS_ERROR_MSG_STRING_SIZE);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe next = (cur+1) % dhp->dh_maxcount;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errs_count++;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_next_to_use = next;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (dhp->dh_next_to_use == dhp->dh_first) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Array is full set full invariant. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_first = (dhp->dh_first+1) % dhp->dh_maxcount;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/* The size of the circular list of strings may be set
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe and reset as desired. Returns the previous size of
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe the list. If the list is shortened excess error entries
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe are simply dropped.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe If the reallocation fails the list size is left unchanged.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Do not make this a long list!
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Remember the maxcount we record is 1 > the user count,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe so we adjust it so it looks like the user count.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Loweunsigned dwarf_set_harmless_error_list_size(Dwarf_Debug dbg,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned maxcount )
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned prevcount = dhp->dh_maxcount;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(maxcount != 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ++maxcount;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(maxcount != dhp->dh_maxcount) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Assign transfers 'ownership' of the malloc areas
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe to oldarray. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe struct Dwarf_Harmless_s oldarray = *dhp;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Do not double increment the max, the init() func
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe increments it too. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_harmless_init(dhp,maxcount-1);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(oldarray.dh_next_to_use != oldarray.dh_first) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned i = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe for(i = oldarray.dh_first; i != oldarray.dh_next_to_use;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe i = (i+1)%oldarray.dh_maxcount) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_insert_harmless_error(dbg,oldarray.dh_errors[i]);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if( oldarray.dh_errs_count > dhp->dh_errs_count) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errs_count = oldarray.dh_errs_count;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dwarf_harmless_cleanout(&oldarray);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return prevcount-1;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowevoid
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned i = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memset(dhp,0,sizeof(*dhp));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_maxcount = size +1;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errors = (char **)malloc(sizeof( char *) *dhp->dh_maxcount);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (!dhp->dh_errors) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_maxcount = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe for(i = 0; i < dhp->dh_maxcount; ++i) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe char *newstr =
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe (char *)malloc(DW_HARMLESS_ERROR_MSG_STRING_SIZE);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errors[i] = newstr;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!newstr) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_maxcount = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Let it leak, the leak is a constrained amount. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errors = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* We make the string content well-defined by an initial
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe NUL byte, but this is not really necessary. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe newstr[0] = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowevoid
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe unsigned i = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if(!dhp->dh_errors) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe for(i = 0; i < dhp->dh_maxcount; ++i) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(dhp->dh_errors[i]);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free(dhp->dh_errors);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_errors = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dhp->dh_maxcount = 0;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe